0

我写了一个练习指针和分配内存的问题。

但是,当我释放内存时,我得到了一个堆栈转储。我在正确的地方释放了吗?我的程序是否还有其他问题可能使其不安全?

void display_names(char **names_to_display, char **output);

int main(void)
{
    char *names[] = {"Luke", "John", "Peter", 0};
    char **my_names = names;
    char *new_output[1024] = {0};
    size_t i = 0;

    // Print the ordinal names
    while(*my_names)
    {
        printf("Name: %s\n", *my_names++);
    }

    my_names = names; /* Reset */
    display_names(my_names, new_output);

    // Print the updated names
    while(new_output[i])
    {
        printf("Full names: %s\n", new_output[i]);
        i++;
    }

    // Free allocated memory
    free(new_output);

    getchar();

    return 0;
}

void display_names(char **names_to_display, char **output)
{
    while(*names_to_display)
    {   
        *output = (char*) malloc(strlen("FullName: ") + strlen(*names_to_display) + 1);
        if(!*output)
        {
            fprintf(stderr, "Cannot allocate memory");
            exit(1);
        }

        // Copy new output
        sprintf(*output, "FullName: %s", *names_to_display++);
        printf("display_names(): Name: %s\n", *output++);
    }   
}
4

3 回答 3

12

您没有为 new_output 分配内存,它是由编译器分配的。free 用于在运行时 malloc 内存时使用,而不是用于在编译时释放编译器分配的内存。

您的 new_output 是一个局部变量,当它超出范围时将被“释放”,即在声明它的函数的右大括号处。

于 2009-06-06T08:50:47.620 回答
7

你的问题是当你说:

free(new_output);

new_output是堆栈上的一个数组。它不是用 malloc() 分配的,所以不能用 free() 释放它。您需要释放new_output包含的指针。

于 2009-06-06T08:51:43.267 回答
7

char* new_display[1024] 的声明意味着您正在声明一个包含 1024 个元素的数组,每个元素都是一个指向 char 的指针。数组本身在这里是静态分配的,栈上会保留一个 1024 个元素的数组。在您的示例中,您通过使用 malloc 分配内存并设置数组的每个元素来填充此数组的条目,这是您应该释放的内存,而不是静态分配的数组本身。

因此,您无需调用 free(new_display),而是需要遍历数组条目并执行 free(new_display[i]),这样您只释放分配的内容。

于 2009-06-06T08:57:53.067 回答