我正在尝试运行以下程序,其中我使用名为reserve的函数动态地将内存分配给变量。当我运行应用程序时,由于在一个单独的函数中为空指针分配内存,我得到分段错误,但是如果我想在main中分配内存,我不会得到这个错误。那么我做错了什么?
以下是代码:
#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);
}
答案 0 :(得分:2)
请注意,context_data
按值传递。因此,reserve
中的本地副本已更改,但不是原始副本。因此,context_data
中的main()
未初始化。所以你得到了崩溃。
答案 1 :(得分:2)
在此代码中:
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
时,context_data
中的main
指针不会更新,从而导致崩溃。
要解决此问题,请接收指向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);
希望这有帮助!
答案 2 :(得分:1)
问题是你的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);
答案 3 :(得分:1)
在通过引用传递时,传递变量的地址。这里你的变量是一个指针,因此传递指针的地址。
称之为:
reserve(length, &context_data, buffer);
并更改功能定义:
void reserve(int length, void **p_context_data ,void *buffer)
{
*p_context_data = malloc(sizeof(char)*length);
.....
答案 4 :(得分:1)
您将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);
}
答案 5 :(得分:1)
函数void* context_data
中的变量reserve()
是一个局部变量,这意味着它与函数char* context_data
中的变量main()
不同。其值不会从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()
函数并使其返回指向已分配内存的指针。