bestsource

어떻게 메모리를 할당하고 (포인터 매개 변수를 통해) 호출 함수에 반환할 수 있습니까?

bestsource 2023. 7. 28. 22:29
반응형

어떻게 메모리를 할당하고 (포인터 매개 변수를 통해) 호출 함수에 반환할 수 있습니까?

다음과 같은 몇 가지 다른 기능에 코드가 있습니다.

void someFunction (int *data) {
  data = (int *) malloc (sizeof (data));
}

void useData (int *data) {
  printf ("%p", data);
}

int main () {
  int *data = NULL;

  someFunction (data);

  useData (data);

  return 0;
}

someFunction ()그리고.useData ()는 별도의 모듈(*.c 파일)에 정의되어 있습니다.

는 malloc에서 사용할 수 입니다.someFunction함수가 반환되면 동일한 메모리를 사용할 수 없습니다.

다양한 메모리 주소를 보여주는 출력과 함께 프로그램 실행 를 볼 수 있습니다.

누가 제가 여기서 무엇을 잘못하고 있는지, 그리고 어떻게 이 코드를 작동시킬 수 있는지 설명해 주시겠습니까?


편집: 그래서 제가 이것을 하기 위해 이중 포인터를 사용해야 할 것 같습니다. 실제로 이중 포인터를 사용해야 할 때 어떻게 같은 일을 할 수 있을까요?예를 들어 데이터는

int **data = NULL; //used for 2D array

그러면 함수 호출에서 트리플 포인터를 사용해야 합니까?

포인터 대 포인터를 사용하려는 경우:

void someFunction (int **data) {
  *data = malloc (sizeof (int));
}

void useData (int *data) {
  printf ("%p", data);
}

int main () {
  int *data = NULL;

  someFunction (&data);

  useData (data);

  return 0;
}

요? 음, 당은당포를바인싶꾸어요고터.data 내용이 .C에서 매개 변수로 전달된 것을 변경하고 호출자 버전에 해당 변경 사항이 표시되도록 하려면 변경할 항목에 대한 포인터를 전달해야 합니다.이 경우, "바꾸고 싶은 것"은 포인터입니다. 그래서 포인터를 변경하려면 포인터 대 포인터를 사용해야 합니다.

주요 문제 외에도 코드에 또 다른 버그가 있었습니다.sizeof(data)포인터를 저장하는 데 필요한 바이트 수(32비트 OS의 경우 4바이트 또는 64비트 OS의 경우 8바이트)를 제공하지만 포인터가 가리키는 것을 저장하는 데 필요한 바이트 수는 실제로 필요합니다.int 일반적으로 냐하면일반로으적왜로▁typically.sizeof(int *)>=sizeof(int)이것은 아마도 문제를 일으키지 않았을 것이지만, 그것은 알아야 할 것입니다.저는 위의 코드에서 이것은 수정했습니다.

포인터 대 포인터에 대한 유용한 질문은 다음과 같습니다.

포인터 포인터는 C에서 어떻게 작동합니까?

여러 수준의 포인터 참조에 사용하시겠습니까?

일반적인 함정, 특히 Java에서 C/C++로 이동한 경우

포인터를 전달할 때 포인터는 값별로 전달됩니다. 즉, 포인터의 값이 복사됩니다.포인터가 가리키는 데이터를 변경하는 데는 좋지만 포인터 자체에 대한 모든 변경은 복사본이기 때문에 로컬일 뿐입니다!

포인터를 e-mallocit 등과 같이 변경하고자 하므로 참조로 전달하는 것이 요령입니다.

**포인터 --> 누비 C 프로그래머를 겁줄 것입니다 ;)

포인터를 수정하려면 포인터를 포인터에 전달해야 합니다.

i. :

void someFunction (int **data) {
  *data = malloc (sizeof (int)*ARRAY_SIZE);
}

edit : ARRAGE_SIZE가 추가되었습니다. 할당할 정수의 수를 알아야 합니다.

포인터 데이터가 값에 의해 다음으로 전달되기 때문입니다.someFunction.

int *data = NULL;
//data is passed by value here.
someFunction (data); 
//the memory allocated inside someFunction  is not available.

포인터로 이동하거나 할당된 포인터를 반환하면 문제가 해결됩니다.

void someFunction (int **data) {
  *data = (int *) malloc (sizeof (data));
}


int*  someFunction (int *data) {
  data = (int *) malloc (sizeof (data));
return data;
}

일부 함수()는 매개 변수를 int*로 사용합니다.따라서 main()에서 호출하면 전달한 값의 복사본이 생성됩니다.함수 내부에서 수정하는 내용은 이 복사본이므로 변경 내용은 외부에 반영되지 않습니다.다른 사용자가 제안한 대로 int**를 사용하여 변경사항을 데이터에 반영할 수 있습니다.다른 방법은 일부 함수()에서 int*를 반환하는 것입니다.

이중 포인터 기술을 사용하는 것 외에, 하나의 반환 매개 변수만 다시 쓰는 것이 필요한 경우 다음과 같습니다.

 int *someFunction () {
   return (int *) malloc (sizeof (int *));
 }

사용:

 int *data = someFunction ();

함수에 메모리를 할당하고 매개 변수를 통해 포인터를 반환하는 일반적인 패턴은 다음과 같습니다.

void myAllocator (T **p, size_t count)
{
  *p = malloc(sizeof **p * count);
}
...
void foo(void)
{
  T *p = NULL;
  myAllocator(&p, 100);
  ...
}

또 다른 방법은 포인터를 함수의 반환 값(내가 선호하는 방법)으로 만드는 것입니다.

T *myAllocator (size_t count)
{
  T *p = malloc(sizeof *p * count);
  return p;
}
...
void foo(void)
{
  T *p = myAllocator(100);
  ...
}

메모리 관리에 대한 몇 가지 참고 사항:

  1. 메모리 관리와 관련된 문제를 방지하는 가장 좋은 방법은 메모리 관리를 피하는 것입니다. 필요한 경우가 아니면 동적 메모리를 사용하지 마십시오.
  2. 1989년 ANSI 표준 이전의 구현체를 사용하거나 코드를 C++로 컴파일하려는 경우가 아니라면 malloc()의 결과를 캐스트하지 마십시오.stdlib.h를 포함하는 것을 잊거나 범위에 malloc()에 대한 프로토타입이 없는 경우 반환 값을 캐스팅하면 귀중한 컴파일러 진단이 억제됩니다.
  3. 데터유크의대할개예크체사기용의를합니다할당신기형이예▁being(▁object사다용니:▁use합▁the▁size▁of▁the▁of▁allocated▁instead) 대신 할당되는 개체의 를 사용합니다.sizeof *psizeof (T)이렇게 하면 데이터 유형이 int에서 long으로 또는 float에서 double로 변경되는 경우 약간의 속쓰림을 줄일 수 있습니다.가 IMO를더 잘 읽히게 . IMO는 IMO를 읽습니다.
  4. 더 높은 수준의 할당 및 할당 해제 기능 뒤에 있는 메모리 관리 기능을 분리합니다. 할당뿐만 아니라 초기화 및 오류도 처리할 수 있습니다.

여기서 포인터를 "data == Null"에서 "data == 0xabcd"로 수정하려고 합니다.따라서 필요한 데이터를 수정하기 위해 데이터의 주소를 전달합니다.& 데이터.

void someFunction (int **data) {
  *data = (int *) malloc (sizeof (int));
}

다음에서 편집한 추가 질문에 대한 답변:

무언가에 대한 포인터를 나타냅니다.그래서 '**'는 어떤 것에 대한 포인터, '***'는 어떤 것에 대한 포인터의 포인터 등이 될 것입니다.

int **data'(데이터가 함수 매개변수가 아닌 경우)에 대한 일반적인 해석은 int 배열 목록에 대한 포인터가 될 것입니다(예: 'inta [100][100]).

따라서 먼저 int 어레이를 할당해야 합니다(간단하게 사용하기 위해 malloc()에 직접 호출합니다).

data = (int**) malloc(arrayCount); //allocate a list of int pointers
for (int i = 0; i < arrayCount; i++) //assign a list of ints to each int pointer
   data [i] = (int*) malloc(arrayElemCount);

이중 포인터를 사용하는 대신 새 포인터를 할당하고 반환하면 됩니다. 함수의 어느 곳에서도 사용되지 않기 때문에 이중 포인터를 전달할 필요가 없습니다.

돌아가다void *모든 유형의 할당에 사용할 수 있습니다.

void *someFunction (size_t size) {
    return  malloc (size);
}

다음과 같이 사용합니다.

int *data = someFunction (sizeof(int));

단순화를 위해 위의 단일 포인터 파라미터 p와 이중 포인터 pp(위쪽을 가리키는 말)를 호출하겠습니다.

함수에서 가리키는 객체는 변경될 수 있고 변경은 함수 밖으로 나갈 수 있습니다.그러나 p 자체가 변경된 경우에는 변경 내용이 함수를 떠나지 않습니다.

불행하게도, malloc는 그 자체의 본질로, 일반적으로 p를 바꿉니다.그것이 원래 코드가 작동하지 않는 이유입니다.보정(58)은 보정된 기능에서 p.를 가리키는 포인터 pp를 사용하며, pp는 변경되지만 pp는 변경되지 않습니다.이렇게 해서 효과가 있었습니다.

언급URL : https://stackoverflow.com/questions/1398307/how-can-i-allocate-memory-and-return-it-via-a-pointer-parameter-to-the-calling

반응형