![](/img/trans.png)
[英]Should memory be allocated using Malloc for this function? Does that cause a segmentation fault?
[英]Allocating memory using malloc in a function, segmentation fault
我正在尝试运行以下程序,在该程序中,我使用称为reserve的函数将内存动态分配给变量。 当我运行应用程序时,由于在空指针的单独函数中分配内存而导致分段错误,但是如果我要在主函数中分配内存,则不会出现此错误。 那我在做什么错?
这是代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct{
unsigned char state;
/* socket fd of the client */
int fd;
/* File path requested by the client */
char file_path [255];
/* Current file offset */
unsigned long int offset;
} STATE;
void reserve(int length, void *context_data ,void *buffer)
{
context_data = (char *) malloc(length);
memcpy(context_data, buffer, length);
}
int main()
{
STATE test;
int length = sizeof(STATE);
char buffer[1500];
char *ptr = buffer;
test.state = 10;
strcpy(test.file_path, "Hello How are you");
memcpy(ptr, &test, length);
ptr += length;
char *context_data;
reserve(length, context_data, buffer);
STATE *temp = (STATE *) context_data;
printf("File Path %s\n", temp->file_path);
printf("State %d\n", temp->state);
}
请注意, context_data
是按值传递的。 因此, reserve
的本地副本已更改,但原始副本未更改。 结果, main()
的context_data
没有初始化。 这样您就崩溃了。
在此代码中:
void reserve(int length, void *context_data ,void *buffer)
{
context_data = (char *) malloc(length);
memcpy(context_data, buffer, length);
}
所述context_data
参数由值来传递,所以context_data
的内部reserve
和context_data
以外reserve
是不一样的指针。 因此,当您在此函数内部本地重新分配context_data
时, main
的context_data
指针不会更新,从而导致崩溃。
要解决此问题,可以采用指向context_data
变量的指针进行更新,如下所示:
void reserve(int length, void **context_data ,void *buffer)
{
*context_data = malloc(length);
memcpy(*context_data, buffer, length);
}
reserve(length, &context_data, buffer);
或者,也可以reserve
返回更新后的指针:
void* reserve(int length,void *buffer)
{
void* context_data = (char *) malloc(length);
memcpy(context_data, buffer, length);
return context_data;
}
void* context_data = reserve(length, buffer);
希望这可以帮助!
问题是您的main()
函数没有当前的学习分配位置的方法。 您正在将指针从main()
传递给reserve()
,这样可以允许子例程修改指针指向的内容……但这不是您所需要的。 你需要有reserve()
修改其中的指针指向。
void reserve(int length, void **context_data ,void *buffer)
{
*context_data = malloc(length);
memcpy(*context_data, buffer, length);
}
// in main():
char *context_data;
reserve(length, &context_data, buffer);
通过引用传递,您传递变量的地址。 这里的变量是一个指针,因此传递指针的地址。
像这样称呼它:
reserve(length, &context_data, buffer);
并更改函数定义:
void reserve(int length, void **p_context_data ,void *buffer)
{
*p_context_data = malloc(sizeof(char)*length);
.....
您将char*
传递给reserve()
但应这样传递char**
:
char *context_data;
reserve(length, &context_data, buffer);
然后reserve
应如下所示:
void reserve(int length, void **context_data ,void *buffer) {
*context_data = (char *) malloc(length);
memcpy(*context_data, buffer, length);
}
函数reserve()
中的变量void* context_data
是局部变量,这意味着它与函数main()
变量char* context_data
不同。 它的值不会从reserve()
传播回main()
reserve()
。 您将context_data
的值传递给reserve()
(未定义的值),然后将其用作STATE* temp
,但该值仍未定义。
如果要更新main()
函数的局部变量,则必须将指针传递给该变量。 在您的情况下,您必须将指针传递给指针,即您的代码应如下所示:
void reserve(int length, void **context_data, void *buffer)
{
*context_data = (char *) malloc(length);
memcpy(*context_data, buffer, length);
}
int main()
{
...
char* context_data;
reserve(length, &context_data, buffer);
...
}
或者,您也可以更改您的reserve()
函数并使它返回指向已分配内存的指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.