C编程:另一个函数中的malloc()

C编程:另一个函数中的malloc(),c,function,pointers,malloc,C,Function,Pointers,Malloc,我需要关于另一个函数中的malloc()的帮助 我正在从我的main()向函数传递一个指针和大小,我想从调用的函数内部使用malloc()动态地为该指针分配内存,但我看到的是。。。。正在分配的内存用于在我调用的函数中声明的指针,而不是main()中的指针 如何将指针传递给函数,并从被调用函数内部为传递的指针分配内存 我已经编写了以下代码,并得到如下所示的输出 来源: int main() { unsigned char *input_image; unsigned int bmp_

我需要关于另一个函数中的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;
}
程序输出:
您需要将指向指针的指针作为参数传递给函数

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; 
} 

如果希望函数修改指针本身,则需要将其作为指向指针的指针传递。下面是一个简化的示例:

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

这没有意义:

if(alloc_pixels(input_image, bmp_image_size)==NULL) 
alloc_pixels
返回一个
signed char
ERROR
NO_ERROR
)并将其与
NULL
(应该用于指针)进行比较

如果要更改
input\u image
,需要将指向它的指针传递到
alloc\u pixels
所有像素
签名如下:

signed char alloc_pixels(unsigned char **ptr, unsigned int size)
你可以这样称呼它:

alloc_pixels(&input_image, bmp_image_size);
以及内存分配

*ptr = malloc(size);
我应该如何将指针传递给 函数,并为 从被调用的 功能

问问自己:如果你必须编写一个必须返回
int
的函数,你会怎么做

您可以直接返回:

int foo(void)
{
    return 42;
}
T* foo(void)
{
    T* p = malloc(...);
    return p;
}
或者通过添加一个级别(即,使用
int*
而不是
int
)通过输出参数返回:

因此,当您返回指针类型(
T*
)时,情况是一样的:您可以直接返回指针类型:

int foo(void)
{
    return 42;
}
T* foo(void)
{
    T* p = malloc(...);
    return p;
}
或者添加一级间接寻址:

void foo(T** out)
{
    assert(out != NULL);
    *out = malloc(...);
}

您需要通过引用而不是复制来传递指针,函数
alloc_pixels
中的参数需要使用与符号&来传递回指针的地址-即在C语言中通过引用调用

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"); } 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; }
在初始代码中,当您将输入图像传递给函数alloc_pixels时,编译器正在创建它的副本(即ptr)并将值存储在堆栈上。将malloc返回的值分配给ptr。一旦函数返回main并且堆栈展开,该值就会丢失。因此,内存仍在堆上分配,但内存位置从未存储(或分配给)input_映像,因此出现了问题

您可以更改函数alloc_pixels的签名,这将更容易理解,并且您也不需要额外的“status”变量

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;
}
您可以在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;

}
只有将值设置为其地址时,参数的赋值才会起作用

在尝试解决此问题之前,您应该了解两点:
1. C函数:传递给函数的所有参数都将是函数中的一个副本

这意味着您在函数中所做的每项赋值都不会影响函数外的变量,您正在处理副本实际上:

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
因此,如果您想更改函数中的i,您需要知道对象及其副本之间的区别:

副本与对象共享值,但不共享地址

这是他们唯一的区别

所以在函数中改变i的唯一方法是使用i的地址

例如,有一个新函数fun_addr:

void fun_addr(int *i) {
    *i = some_value;
}
这样,您可以更改i的值

  • malloc
  • fun_addr函数的关键点是,您已经向该函数传递了一个地址。您可以更改存储在该地址中的值

    马洛克会怎么做

    malloc将分配一个新的内存空间,并返回指向该地址的指针

    请看以下说明:

    int *array = (int*) malloc(sizeof(int) * SIZE);
    
    您要做的是让数组的值等于malloc返回的地址

    看到了吗?这是同一个问题,为传递给函数的参数永久赋值。此时,值为
    地址

    现在,将地址(由malloc返回)分配给地址(存储旧地址)

    因此,代码应该是:

    void fun_addr_addr(int **p) {
        *p = (int*) malloc(sizeof(int) * SIZE);
    }
    

    这一个会起作用。

    这是唯一一种让指针指向指针解决方案的方法,可以解决我在这个函数中遇到的类似问题

        BOOL OpenBitmap2 ( LPCTSTR pszFileName, char** pszBMPFile)  
    
    是通过分配一个临时指针来存储地址

        char* BMPFile;
        { BMPFile = (char*)GlobalAlloc(GPTR, dwFileSize + 1);   // allocate storage using GlobalAlloc + 1 for null term string
    
    然后重新分配它

        {* pszBMPFile = BMPFile; return (0);} // Error = False
    
    如果您对GlobalAlloc直接使用“*pszBMPFile”无效的原因有任何评论,我们将不胜感激。
    我回答了我自己的问题。我忘了在其他代码行中使用pszBMPFile完成“*”。来自所有贡献者的好教训。非常感谢。

    如其他答案所述,我们需要指向指针的指针。但是为什么呢

    我们需要通过指针传递该值,以便能够修改该值。如果要修改
    int
    ,需要通过
    int*
    传递它

    在这个问题中,我们要修改的值是一个指针
    int*
    (指针从
    NULL
    更改为分配内存的地址),因此我们需要传递一个指向指针
    int**

    通过执行以下操作,
    pInt
    inside
    foo(int*)
    是参数的副本。当我们将内存分配给局部变量时,
    main()
    中的内存是完整的

    void foo(int* pInt)
    {
       pInt = malloc(...);
    }
    int main()
    {
       int* pInt;
       foo(pInt);
       return 0;
    }
    
    所以我们需要一个指向指针的指针

    void foo(int** pInt)
    {
       *pInt = malloc(...);
    }
    int main()
    {
       int* pInt;
       foo(&pInt);
       return 0;
    }
    
    在空点上调用
    free()
    是安全的
    void foo(int** pInt)
    {
       *pInt = malloc(...);
    }
    int main()
    {
       int* pInt;
       foo(&pInt);
       return 0;
    }