Ошибка при освобождении памяти в C - PullRequest
0 голосов
/ 06 июня 2009

Я написал задачу для практики указателей и выделения памяти.

Однако при освобождении памяти я получаю дамп стека. Я освобождаюсь в правильном месте? Что-то не так с моей программой, которая может сделать ее небезопасной?

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++);
    }   
}

Ответы [ 3 ]

12 голосов
/ 06 июня 2009

Вы не выделили память для new_output, она была выделена компилятором. free используется для использования памяти malloc во время выполнения, а не для освобождения памяти, выделенной компилятором во время компиляции.

Ваш new_output является локальной переменной и будет «освобожден», когда выйдет из области видимости, то есть на закрывающей скобке функции, в которой он объявлен.

7 голосов
/ 06 июня 2009

объявление char * new_display [1024] означает, что вы объявляете массив из 1024 элементов, каждый элемент является указателем на char. Сам массив здесь статически размещен, массив из 1024 элементов будет зарезервирован в стеке. В вашем примере вы заполняете записи этого массива, выделяя память с помощью malloc и устанавливая каждый элемент массива, это память, которую вы должны освободить, а не сам статически распределенный массив.

Таким образом, вместо вызова free (new_display), вам нужно будет перебрать записи массива и сделать free (new_display [i]), таким образом вы освобождаете только то, что вы выделили. *

7 голосов
/ 06 июня 2009

Ваша проблема в том, что когда вы говорите:

free(new_output);

new_output - это массив в стеке. Он не был выделен с помощью malloc (), поэтому вы не можете освободить его с помощью free (). Вам нужно освободить указатели, которые содержит new_output.

...