繁体   English   中英

在函数中使用malloc分配内存,出现分段错误

[英]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的内部reservecontext_data以外reserve是不一样的指针。 因此,当您在此函数内部本地重新分配context_data时, maincontext_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM