3

如果我有以下代码,我在主函数中分配我的内存,然后将它传递给一个函数,它会像这样为我填充它:

main()
{
    char *bar = (char*) malloc(sizeof(char));

    while(1)
    {
        foo(bar);
        free(bar);
        bar = (char*) malloc(sizeof(char));
    }
}

foo(char *bar)
{
    int c;
    int i = 0;
    while((c = getchar()) != '\n' && c != EOF)
    {
        bar[i++] = c;
        bar = (char*) realloc(bar, sizeof(char) * (i+1));
    }
}

几次输入后我得到一个段错误。但是,如果我这样做:

main()
{
    char *bar;

    while(1)
    {
        bar = foo();
        free(bar);
    }
}

char *foo()
{
    char *bar = (char*) malloc(sizeof(char));
    int c;
    int i = 0;
    while((c = getchar()) != '\n' && c != EOF)
    {
        bar[i++] = c;
        bar = (char*) realloc(bar, sizeof(char) * (i+1));
    }

    return bar;
}

,即把内存分配给函数,一切似乎工作正常。这是为什么?

4

4 回答 4

4

这是非常预期的行为。realloc() 可能会也可能不会将传递给它的指针“移动”到新地址。如果发生这种情况,它也是 free() 的原始地址。由于 C 是按值传递而不是按引用传递,因此barmain() 函数中的指针仍将引用旧地址,并且您将有效地执行双重释放(以及 realloc() 的指针会迷路)。

于 2013-01-15T18:44:02.697 回答
2

C 是一种按值传递的语言。您对bar内部的修改foo()不会影响该bar函数调用的外部。要执行您想要执行的操作,您需要将该参数更改为 bechar **bar并将其*bar用作foo().

一些编辑说明:

  1. 您不需要在 C中转换malloc()or的返回值。realloc()

  2. 不要分配给你传入的同一个指针realloc()。如果它失败了,你会得到一个内存泄漏。

  3. sizeof(char)1,为什么要打扰额外的打字?

于 2013-01-15T18:41:40.653 回答
0

在第一种情况下,您可能会释放两次内存。该realloc调用可以将另一块内存交还给您,在这种情况下,第一个块(在 main 中分配的那个)被释放。

于 2013-01-15T18:42:33.350 回答
0

realloc不会总是扩展相同的内存。如果无法扩展,有时它会分配新的内存块。

main()
{
    char *bar = (char*) malloc(sizeof(char));

    while(1)
    {
        foo(&bar);
        free(bar);
        bar = (char*) malloc(sizeof(char));
    }
}

foo(char **dbar)
{
    char *bar = *dbar;
    int c;
    int i = 0;
    while((c = getchar()) != '\n' && c != EOF)
    {
        bar[i++] = c;
        bar = (char*) realloc(bar, sizeof(char) * (i+1));
    }
    *dbar = bar;
}
于 2013-01-15T18:45:30.103 回答