C编程:另一个函数中的malloc()
我需要另一个函数内的 malloc()帮助。
我从我的main()传递一个指针和大小的函数,我想分配内存为该指针dynamic使用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; }
所以当你返回一个指针types( T* )时,它是一样的:你直接返回指针types:
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语言中的引用调用 。
主要()
{
无符号字符* input_image;
unsigned int bmp_image_size = 262144;
如果(alloc_pixels(&input_image,bmp_image_size)== NULL)
printf(“\ nPoint2:分配的内存:%d个字节”,_ msize(input_image));
其他
printf(“\ nPoint3:内存未分配”);
}
有符号字符alloc_pixels(无符号char ** ptr,无符号整数大小)
{
signed char status = NO_ERROR;
* ptr = NULL;
* ptr =(unsigned char *)malloc(size);
如果((* ptr)== NULL)
{
status = ERROR;
/ *免费(ptr);
printf(“\ nERROR:内存分配没有成功完成!”); * /
}
printf(“\ nPoint1:分配的内存:%d个字节”,_ msize(* ptr));
退货状态;
}
我在alloc_pixels函数中注释掉了两行free(ptr)和“ERROR:…”,这是令人困惑的。 如果内存分配失败,则不需要free指针。
编辑:看到由OP提供的msdn链接后,一个build议,代码示例是在我的答案….早前相同…但更改格式说明符%u为size_ttypes,在printf(...)在main()调用。
主要()
{
无符号字符* input_image;
unsigned int bmp_image_size = 262144;
如果(alloc_pixels(&input_image,bmp_image_size)== NULL)
printf(“\ nPoint2:分配的内存:%u个字节”,_ msize(input_image));
其他
printf(“\ nPoint3:内存未分配”);
}
这没有意义:
if(alloc_pixels(input_image, bmp_image_size)==NULL)
alloc_pixels返回一个有signed char ( ERROR或NO_ERROR ),并将其与NULL (应该用于指针)进行比较。
如果你想要改变input_image ,你需要传递一个指向alloc_pixels的指针。 alloc_pixels签名将如下所示:
signed char alloc_pixels(unsigned char **ptr, unsigned int size)
你会这样称呼它:
alloc_pixels(&input_image, bmp_image_size);
和内存分配
*ptr = malloc(size);
在最初的代码中,当你将input_image传递给函数alloc_pixels时,编译器正在创build它的副本(即ptr)并将值存储在堆栈中。 您将由malloc返回的值分配给ptr。 一旦函数返回到main并且堆栈展开,该值就会丢失。 所以,内存仍然分配在堆上,但内存位置从来没有存储在(或分配给)input_image,因此这个问题。
你可以改变函数alloc_pixels的签名,这会更容易理解,而且你也不需要额外的'status'variables。
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; }
主要可以调用上面的函数:
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; }
参数的赋值只有在你设置该值为其地址的情况下才有效 。
在你尝试解决这个问题之前,你应该知道两点:
1. C函数 :传递给函数的所有参数都是函数中的副本。
这意味着你在函数中所做的每一个赋值都不会影响函数之外的variables,实际上你正在处理这个拷贝 :
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
所以,如果你想改变我的function,你需要知道事情和它的副本之间的区别:
副本与事物共享价值 ,但不是地址 。
这是他们唯一的区别。
所以改变函数的唯一方法就是使用i的地址。
例如,有一个新的函数fun_addr:
void fun_addr(int *i) { *i = some_value; }
这样,你可以改变我的价值。
- malloc :
fun_addr函数的关键点是,你已经传递了一个地址给函数。 你可以改变存储在该地址的值。
malloc会做什么?
malloc将分配一个新的内存空间,并返回指向该地址的指针 。
看这个指令:
int *array = (int*) malloc(sizeof(int) * SIZE);
你在做的是让数组的值等于malloc返回的地址。
看到? 这是同样的问题,永久赋值给传递给函数的参数。 此时,值是address 。
现在,将地址(由malloc返回)分配给地址(存储旧地址)。
所以代码应该是:
void fun_addr_addr(int **p) { *p = (int*) malloc(sizeof(int) * SIZE); }
这一个将工作。