C 프로그래밍 : 다른 함수 내부의 malloc ()
malloc()
다른 기능 내부에 대한 도움이 필요 합니다 .
포인터 와 크기 를 함수에 전달하고 있으며 호출 된 함수 내부에서 main()
사용하여 해당 포인터에 대한 메모리를 동적으로 할당하고 싶습니다 malloc()
. 그러나 제가 보는 것은 ... 할당되는 메모리는 다음과 같습니다. 내 호출 된 함수 내에서 선언 된 포인터에 대해 main()
.
함수에 대한 포인터를 전달 하고 호출 된 함수 내부에서 전달 된 포인터에 대한 메모리를 할당하려면 어떻게해야 합니까?
다음 코드를 작성했으며 아래와 같이 출력을 얻습니다.
출처:
int main()
{
unsigned char *input_image;
unsigned int bmp_image_size = 262144;
if(alloc_pixels(input_image, bmp_image_size)==NULL)
printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image));
else
printf("\nPoint3: Memory not allocated");
return 0;
}
signed char alloc_pixels(unsigned char *ptr, unsigned int size)
{
signed char status = NO_ERROR;
ptr = NULL;
ptr = (unsigned char*)malloc(size);
if(ptr== NULL)
{
status = ERROR;
free(ptr);
printf("\nERROR: Memory allocation did not complete successfully!");
}
printf("\nPoint1: Memory allocated: %d bytes",_msize(ptr));
return status;
}
프로그램 출력 :
Point1: Memory allocated ptr: 262144 bytes
Point2: Memory allocated input_image: 0 bytes
함수에 대한 매개 변수로 포인터에 대한 포인터를 전달해야합니다.
int main()
{
unsigned char *input_image;
unsigned int bmp_image_size = 262144;
if(alloc_pixels(&input_image, bmp_image_size) == NO_ERROR)
printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image));
else
printf("\nPoint3: Memory not allocated");
return 0;
}
signed char alloc_pixels(unsigned char **ptr, unsigned int size)
{
signed char status = NO_ERROR;
*ptr = NULL;
*ptr = (unsigned char*)malloc(size);
if(*ptr== NULL)
{
status = ERROR;
free(*ptr); /* this line is completely redundant */
printf("\nERROR: Memory allocation did not complete successfully!");
}
printf("\nPoint1: Memory allocated: %d bytes",_msize(*ptr));
return status;
}
함수에 대한 포인터를 전달하고 호출 된 함수 내부에서 전달 된 포인터에 대한 메모리를 할당하려면 어떻게해야합니까?
스스로에게 물어보십시오.를 반환해야하는 함수를 작성 int
해야한다면 어떻게 하시겠습니까?
직접 반환 할 수 있습니다.
int foo(void)
{
return 42;
}
또는 레벨에 추가하여, 출력 파라미터를 통해 반환 간접 (사용 예를 int*
대신 int
)
void foo(int* out)
{
assert(out != NULL);
*out = 42;
}
따라서 포인터 유형 ( T*
)을 반환 할 때도 마찬가지입니다. 포인터 유형을 직접 반환하거나 :
T* foo(void)
{
T* p = malloc(...);
return p;
}
또는 한 수준의 간접 참조를 추가합니다.
void foo(T** out)
{
assert(out != NULL);
*out = malloc(...);
}
함수가 포인터 자체를 수정하도록하려면 포인터에 대한 포인터로 전달해야합니다. 다음은 간단한 예입니다.
void allocate_memory(char **ptr, size_t size) {
void *memory = malloc(size);
if (memory == NULL) {
// ...error handling (btw, there's no need to call free() on a null pointer. It doesn't do anything.)
}
*ptr = (char *)memory;
}
int main() {
char *data;
allocate_memory(&data, 16);
}
포인터 를 복사가 아닌 참조 로 전달해야 합니다. 함수의 매개 변수 alloc_pixels
는 앰퍼샌드 &를 사용하여 포인터의 주소를 다시 전달해야합니다. 즉 , C에서 참조 로 호출됩니다 .
본관() { unsigned char * input_image; unsigned int bmp_image_size = 262144; if (alloc_pixels (& input_image, bmp_image_size) == NULL) printf ( "\ nPoint2 : 할당 된 메모리 : % d 바이트", _msize (input_image)); 그밖에 printf ( "\ nPoint3 : 할당되지 않은 메모리"); } 부호있는 char alloc_pixels (unsigned char ** ptr, unsigned int 크기) { 서명 된 문자 상태 = NO_ERROR; * ptr = NULL; * ptr = (부호없는 문자 *) malloc (size); if ((* ptr) == NULL) { 상태 = 오류; / * 무료 (ptr); printf ( "\ n 오류 : 메모리 할당이 성공적으로 완료되지 않았습니다!"); * / } printf ( "\ nPoint1 : 할당 된 메모리 : % d 바이트", _msize (* ptr)); 반환 상태; }
혼란 스럽기 때문에 함수 free(ptr)
내에서 두 줄 과 "ERROR : ..."를 주석 처리했습니다 alloc_pixels
. free
메모리 할당이 실패하면 포인터 가 필요하지 않습니다 .
편집 : 상기보고 후 MSDN의 영업 이익, 제안에 의해 공급 링크, 코드 샘플에 형식 지정을 변경 ... 내 대답에 이전과 동일합니다 ....하지만 %u
에 대한 size_t
에서, 유형 printf(...)
의 전화 main()
.
본관() { unsigned char * input_image; unsigned int bmp_image_size = 262144; if (alloc_pixels (& input_image, bmp_image_size) == NULL) printf("\nPoint2: Memory allocated: %u bytes",_msize(input_image)); else printf("\nPoint3: Memory not allocated"); }
This does not make sense :
if(alloc_pixels(input_image, bmp_image_size)==NULL)
alloc_pixels
returns a signed char
(ERROR
or NO_ERROR
) and you compare it to NULL
(which is supposed to be used for pointers).
If you want input_image
to be changed, you need to pass a pointer to it to alloc_pixels
. alloc_pixels
signature would be the following:
signed char alloc_pixels(unsigned char **ptr, unsigned int size)
You would call it like this:
alloc_pixels(&input_image, bmp_image_size);
And the memory allocation
*ptr = malloc(size);
In your initial code , when you were passing input_image to the function alloc_pixels, compiler was creating a copy of it (i.e. ptr) and storing the value on the stack. You assign the value returned by malloc to ptr. This value is lost once the function returns to main and the stack unwinds. So, the memory is still allocated on heap but the memory location was never stored in (or assigned to )input_image, hence the issue.
You can change the signature of the function alloc_pixels which would be simpler to understand, and you won't require the additional 'status' variable as well.
unsigned char *alloc_pixels(unsigned int size)
{
unsigned char *ptr = NULL;
ptr = (unsigned char *)malloc(size);
if (ptr != NULL)
printf("\nPoint1: Memory allocated: %d bytes",_msize(ptr));
return ptr;
}
You can call the above function in main :
int main()
{
unsigned char *input_image;
unsigned int bmp_image_size = 262144;
if((input_image = alloc_pixels(bmp_image_size))==NULL)
printf("\nPoint3: Memory not allocated");
else
printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image));
return 0;
}
Parameters' assignment will work only if you set the value to its address.
There are 2 points that you should know before you attempt to solve this problem:
1. C Function: All the parameters you passed to the function will be a copy in the function.
That means every assignment that you've made in the function will not affect the variables outside the function, you're working on the copy actually:
int i = 1;
fun(i);
printf("%d\n", i);
//no matter what kind of changes you've made to i in fun, i's value will be 1
So, if you want to change i in the function, you need to know the difference between the thing and its copy:
The copy shared the value with the thing, but not the address.
And that's their only difference.
So the only way to change i in the function is using the address of i.
For example, there's a new function fun_addr:
void fun_addr(int *i) {
*i = some_value;
}
In this way, you could change i's value.
- malloc:
The key point in the fun_addr function is, you've passed a address to the function. And you could change the value stored in that address.
What will malloc do?
malloc will allocate a new memory space, and return the pointer pointed to that address back.
Look at this instruction:
int *array = (int*) malloc(sizeof(int) * SIZE);
What you are doing is let array's value equals to the address returned by malloc.
See? This is the same question, permanently assigning value to the parameter passed to the function. At this point, the value is address
.
Now, assign the address(returned by malloc) to the address(stores the old address).
So the code should be:
void fun_addr_addr(int **p) {
*p = (int*) malloc(sizeof(int) * SIZE);
}
This one will work.
The only way I could get pointer to a pointer solution to work for a similar problem I was having for this function
BOOL OpenBitmap2 ( LPCTSTR pszFileName, char** pszBMPFile)
Was by assigning a temporary pointer to store the address
char* BMPFile;
{ BMPFile = (char*)GlobalAlloc(GPTR, dwFileSize + 1); // allocate storage using GlobalAlloc + 1 for null term string
then reassigning it
{* pszBMPFile = BMPFile; return (0);} // Error = False
Any comment on why using "* pszBMPFile" directly with GlobalAlloc didn't work would be appreciated. I answered my own question. I forgot to carry the "*" through with pszBMPFile in the other lines of code. Good lessons from all the contributors. Many thanks.
참고URL : https://stackoverflow.com/questions/2838038/c-programming-malloc-inside-another-function
'IT Share you' 카테고리의 다른 글
iOS 7 (4 인치 레티 나 디스플레이)에서 앱을 실행할 때 검은 색 막대가 표시됨 (0) | 2020.12.02 |
---|---|
iPhone 6/6 Plus 가로 전용 앱의 시작 이미지를 어떻게 생성합니까? (0) | 2020.12.02 |
자바 : 객체를 byte []로, byte []를 객체로 변환기 (도쿄 내각 용) (0) | 2020.12.02 |
Django에서 AJAX를 통해 매개 변수를 게시하는 동안 "CSRF 토큰이 없거나 잘못되었습니다." (0) | 2020.12.02 |
ansible에서 ansible을 실행하는 사용자의 이름으로 변수를 얻으려면 어떻게해야합니까? (0) | 2020.12.02 |