어떻게 메모리를 할당하고 (포인터 매개 변수를 통해) 호출 함수에 반환할 수 있습니까?
다음과 같은 몇 가지 다른 기능에 코드가 있습니다.
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)
이것은 아마도 문제를 일으키지 않았을 것이지만, 그것은 알아야 할 것입니다.저는 위의 코드에서 이것은 수정했습니다.
포인터 대 포인터에 대한 유용한 질문은 다음과 같습니다.
일반적인 함정, 특히 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);
...
}
메모리 관리에 대한 몇 가지 참고 사항:
- 메모리 관리와 관련된 문제를 방지하는 가장 좋은 방법은 메모리 관리를 피하는 것입니다. 필요한 경우가 아니면 동적 메모리를 사용하지 마십시오.
- 1989년 ANSI 표준 이전의 구현체를 사용하거나 코드를 C++로 컴파일하려는 경우가 아니라면 malloc()의 결과를 캐스트하지 마십시오.stdlib.h를 포함하는 것을 잊거나 범위에 malloc()에 대한 프로토타입이 없는 경우 반환 값을 캐스팅하면 귀중한 컴파일러 진단이 억제됩니다.
- 데터유크의대할개예크체사기용의를합니다할당신기형이예▁being(▁object사다용니:▁use합▁the▁size▁of▁the▁of▁allocated▁instead) 대신 할당되는 개체의 를 사용합니다.
sizeof *p
에sizeof (T)
이렇게 하면 데이터 유형이 int에서 long으로 또는 float에서 double로 변경되는 경우 약간의 속쓰림을 줄일 수 있습니다.가 IMO를더 잘 읽히게 . IMO는 IMO를 읽습니다. - 더 높은 수준의 할당 및 할당 해제 기능 뒤에 있는 메모리 관리 기능을 분리합니다. 할당뿐만 아니라 초기화 및 오류도 처리할 수 있습니다.
여기서 포인터를 "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
'bestsource' 카테고리의 다른 글
base 64 각도의 문자열 인코딩 및 디코딩(2+) (0) | 2023.07.28 |
---|---|
Oracle에 대한 EF 쿼리가 "ORA-12704: 문자 집합 불일치"를 발생시킵니다. (0) | 2023.07.28 |
오라클 인스턴스가 pfile 또는 spfile을 사용하여 시작되었는지 확인하는 방법은 무엇입니까? (0) | 2023.07.28 |
사진 이름을 데이터베이스에서 만든 날짜로 설정하는 것이 사진의 이름을 고유하게 지정하는 가장 좋은 방법입니까? (0) | 2023.07.28 |
Spring Data JPA 저장소 메서드에서 @Query 정의를 사양과 결합할 수 있습니까? (0) | 2023.07.28 |