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_t
types,在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); }
这一个将工作。