-3

我正在做一个项目,我不断收到分段错误,并且结构的值没有被传递。弄清楚为什么让我发疯。我试过用更简单的程序来解决问题,我想我已经找到了问题,但我不确定如何解决它。

问题是,当我“malloc”一个结构时,然后按值传递,值就会丢失。稍后添加“免费”会产生分段错误。我不想从“malloc()”之前或“free()”之后访问一个值,所以我对为什么会这样感到困惑。

这是一个简单的问题模型:

#include <stdlib.h>
#include <stdio.h>

    struct structexample
    {
        int element;
    };

    void initStruct(struct structexample * teststruct, int * number)
    {
        teststruct = malloc(sizeof(struct structexample)); 
        teststruct->element = 10;
        printf("teststruct element is %d in initStruct\n", teststruct->element);
        *number = 5;
    }

    void printtest(struct structexample * teststruct, int * number)
    {
        printf("teststruct element is %d in printtest\n", teststruct->element);
        printf("Number is %d\n", *number);
        free(teststruct);
    }

int main()
{
    int number;
    struct structexample teststruct;
    initStruct(&teststruct, &number);
    printtest(&teststruct, &number);
    printf("teststruct element is %d in main()", teststruct.element);
    return 0;
}

这会产生:

teststruct element is 10 in initStruct
teststruct element is -7967792 in printtest
Number is 5
Segmentation fault

我用“gcc -Wall -pedantic -ansi”编译程序,没有得到任何错误或警告。

当我注释掉“malloc”和“free”时,它会正确产生:

teststruct element is 10 in initStruct
teststruct element is 10 in printtest
Number is 5

如果我只注释掉“free”但留下“malloc”,则可以修复分段错误,但结构的值仍然不正确。在这个简单的程序中,我真的不需要“malloc()”和“free()”,但在我的大型项目中确实需要它们。如果我能让他们在这个更简单的程序中工作,那么我想我可以修复更大的程序。不幸的是,我在 Google 上找不到类似的问题。

4

3 回答 3

1

只需从中删除该free()行,printtest()它看起来像这样:

void printtest(struct structexample * teststruct, int * number)
{
    printf("teststruct element is %d in printtest\n", teststruct->element);
    printf("Number is %d\n", *number);
}

发生分段错误是因为您试图释放堆栈上的内存!

您也可以删除该malloc()行,initStruct()因为它没有用:它为 a 分配空间struct structexample并将其地址返回到在堆上分配并传递给的地址teststructstruct structexample *这意味着一旦调用返回initStruct(),它将丢失。initStruct()

于 2016-02-29T19:40:22.993 回答
1

您正在混合堆栈和堆

void initStruct(struct structexample * teststruct, int * number)
 {
     teststruct = malloc(sizeof(struct structexample)); 
     ^ There is no need to use malloc, teststruct is on the stack

 ...

int main()
{
    int number;
    struct structexample teststruct;
    initStruct(&teststruct, &number);
于 2016-02-29T18:17:21.117 回答
0
void initStruct(struct structexample * teststruct, int * number)
{
    teststruct = malloc(sizeof(struct structexample)); 
    teststruct->element = 10;
    printf("teststruct element is %d in initStruct\n", teststruct->element);
    *number = 5;
}

你向这个函数传递一个值,一个结构的地址,它完全忽略了它。它用 分配malloc,但对它返回的地址不做任何事情。它不返回它。它不会把它放在任何其他代码可以得到它的地方。所以你刚刚泄露了这个对象。

void printtest(struct structexample * teststruct, int * number)
{
    printf("teststruct element is %d in printtest\n", teststruct->element);
    printf("Number is %d\n", *number);
    free(teststruct);
}

所以printtest传递teststructfree,所以它应该传递一个从 返回的值malloc

struct structexample teststruct;
initStruct(&teststruct, &number);
printtest(&teststruct, &number);

但是您传递printtest的地址teststruct是在堆栈上分配的。这不可能。

你期待initStruct以某种方式移动teststruct吗?它肯定不能那样做。

于 2016-02-29T18:22:38.720 回答