C语言 C 编程:malloc() 在另一个函数中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2838038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C Programming: malloc() inside another function
提问by HaggarTheHorrible
I need help with malloc()inside another function.
我需要malloc()另一个函数内部的帮助。
I'm passing a pointerand sizeto the function from my main()and I would like to allocate memory for that pointer dynamically using malloc()from inside that called function, but what I see is that.... the memory, which is getting allocated, is for the pointer declared within my called function and not for the pointer which is inside the main().
我正在从我的函数传递一个指针和大小main(),我想malloc()从被调用的函数内部动态地使用该指针为该指针分配内存,但我看到的是......正在分配的内存是对于在我调用的函数中声明的指针,而不是在main().
How should I pass a pointer to a function and allocate memory for the passed pointer from inside the called function?
我应该如何将指针传递给函数并从被调用函数内部为传递的指针分配内存?
I have written the following code and I get the output as shown below.
我编写了以下代码,并得到如下所示的输出。
SOURCE:
来源:
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;
}
PROGRAM OUTPUT:
程序输出:
Point1: Memory allocated ptr: 262144 bytes
Point2: Memory allocated input_image: 0 bytes
回答by jamesdlin
How should I pass a pointer to a function and allocate memory for the passed pointer from inside the called function?
我应该如何将指针传递给函数并从被调用函数内部为传递的指针分配内存?
Ask yourself this: if you had to write a function that had to return an int, how would you do it?
问问自己:如果您必须编写一个必须返回 的函数,int您会怎么做?
You'd either return it directly:
你要么直接返回它:
int foo(void)
{
return 42;
}
or return it through an output parameter by adding a level of indirection(i.e., using an int*instead of int):
或者通过添加一个间接级别(即,使用int*代替int)通过输出参数返回它:
void foo(int* out)
{
assert(out != NULL);
*out = 42;
}
So when you're returning a pointer type (T*), it's the same thing: you either return the pointer type directly:
因此,当您返回指针类型 ( T*) 时,情况是一样的:您要么直接返回指针类型:
T* foo(void)
{
T* p = malloc(...);
return p;
}
or you add one level of indirection:
或者您添加一级间接:
void foo(T** out)
{
assert(out != NULL);
*out = malloc(...);
}
回答by Mark Ransom
You need to pass a pointer to a pointer as the parameter to your function.
您需要将指向指针的指针作为参数传递给您的函数。
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;
}
回答by Matti Virkkunen
If you want your function to modify the pointer itself, you'll need to pass it as a pointer to a pointer. Here's a simplified example:
如果您希望函数修改指针本身,则需要将其作为指向指针的指针传递。这是一个简化的示例:
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);
}
回答by t0mm13b
You need to pass the pointer by reference, not by copy, the parameter in the function alloc_pixelsrequires the ampersand & to pass back out the address of the pointer - that is call by referencein C speak.
您需要通过引用传递指针,而不是通过复制,函数中的参数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;
}
I have commented out the two lines free(ptr)and "ERROR: ..." within the alloc_pixelsfunction as that is confusing. You do not need to freea pointer if the memory allocation failed.
我已经注释掉了函数中的两行free(ptr)和“错误:...”,alloc_pixels因为这令人困惑。free如果内存分配失败,则不需要指针。
Edit:After looking at the msdnlink supplied by OP, a suggestion, the code sample is the same as earlier in my answer.... but...change the format specifier to %ufor the size_ttype, in the printf(...)call in main().
编辑:看后MSDN由OP,建议提供链接,代码样本是一样的早些时候在我的答案....但...改变格式说明符%u的size_t类型,在printf(...)呼叫main()。
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");
}
回答by Bertrand Marron
This does not make sense :
这根本不符合逻辑 :
if(alloc_pixels(input_image, bmp_image_size)==NULL)
alloc_pixelsreturns a signed char(ERRORor NO_ERROR) and you compare it to NULL(which is supposed to be used for pointers).
alloc_pixels返回一个signed char(ERROR或NO_ERROR) 并将其与NULL( 应该用于指针) 进行比较。
If you want input_imageto be changed, you need to pass a pointer to it to alloc_pixels.
alloc_pixelssignature would be the following:
如果要input_image更改,则需要将指向它的指针传递给alloc_pixels.
alloc_pixels签名如下:
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);
回答by juventus
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.
在您的初始代码中,当您将 input_image 传递给函数 alloc_pixels 时,编译器正在创建它的副本(即 ptr)并将值存储在堆栈中。您将 malloc 返回的值分配给 ptr。一旦函数返回 main 并且堆栈展开,这个值就会丢失。因此,内存仍然在堆上分配,但内存位置从未存储在(或分配给)input_image 中,因此存在问题。
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.
您可以更改函数 alloc_pixels 的签名,这会更容易理解,并且您也不需要额外的“状态”变量。
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 :
您可以在 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;
}
回答by VELVETDETH
Parameters' assignment will work only if you set the value to its address.
仅当您将值设置为其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.
在尝试解决此问题之前,您应该了解 2 点:
1. C 函数:您传递给函数的所有参数都将是函数中的副本。
That means every assignment that you've made in the function will not affect the variables outside the function, you're working on the copyactually:
这意味着您在函数中所做的每个赋值都不会影响函数外部的变量,您实际上是在处理副本:
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:
所以,如果你想在函数中改变 i ,你需要知道事物和它的副本之间的区别:
The copy shared the valuewith 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.
所以在函数中改变 i 的唯一方法是使用 i 的地址。
For example, there's a new function fun_addr:
例如,有一个新函数 fun_addr:
void fun_addr(int *i) {
*i = some_value;
}
In this way, you could change i's value.
通过这种方式,您可以更改 i 的值。
- 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.
fun_addr 函数的关键在于,您已将地址传递给该函数。您可以更改存储在该地址中的值。
What will malloc do?
malloc 会做什么?
malloc will allocate a new memory space, and return the pointer pointed to that address back.
malloc 将分配一个新的内存空间,并将指向该地址的指针返回。
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.
您正在做的是让数组的值等于 malloc 返回的地址。
See? This is the same question, permanently assigning value to the parameter passed to the function. At this point, the value is address.
看?这是同一个问题,永久地为传递给函数的参数赋值。此时,值为address。
Now, assign the address(returned by malloc) to the address(stores the old address).
现在,将地址(由 malloc 返回)分配给地址(存储旧地址)。
So the code should be:
所以代码应该是:
void fun_addr_addr(int **p) {
*p = (int*) malloc(sizeof(int) * SIZE);
}
This one will work.
这个会起作用。
回答by PeterS
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.
关于为什么直接在 GlobalAlloc 中使用“* pszBMPFile”不起作用的任何评论将不胜感激。我回答了我自己的问题。我忘记在其他代码行中使用 pszBMPFile 传递“*”。来自所有贡献者的良好教训。非常感谢。

