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 に答える