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议,代码示例是在我的答案….早前相同…但更改格式说明符%usize_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 charERRORNO_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; } 

这样,你可以改变我的价值。

  1. 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); } 

这一个将工作。