-4

多次元配列を返す関数を定義しました。

行の割り当て

arr = (char **)malloc(size);

列の割り当て (ループ内)

arr[i] = (char *)malloc(v);

戻り値の型は char** です

メモリの解放を除いて、すべて正常に動作します。関数によって返された配列で free(arr[i]) および/または free(arr) を呼び出すと、クラッシュします。

編集:

関数の割り当て

pole = malloc(zaznamov);  
char ulica[52], t[52], datum[10];  
float dan;  
int i = 0, v;
*max = 0;
while (!is_eof(f))
{
    get_record(t, ulica, &dan, datum, f);
    v = strlen(ulica);
pole[i] = malloc(v);
strcpy(pole[i], ulica);
pole[i][v-1] = '\0';
if (v - 1 > *max)
{
    *max = v;
}
i++;
}
return pole;

関数を呼び出しているメインの部分

pole = function();

メモリ解放

int i;
for (i = 0; i < zaznamov; i++)  
{  
    free(pole[i]);  
    pole[i] = NULL;  
}  
free(pole);  
pole = NULL;
4

2 に答える 2

0

完全な割り当てコードを表示しないため、何が間違っているのかを知るのは困難です。私たちが見たものを考えると、あなたは次のようになるはずです:

size_t n = 27;
size_t size = n * sizeof(char *);
char **arr = (char **)malloc(size);
size_t v = 39;

if (arr == 0)
    ...report error and bail out...

for (size_t i = 0; i < n; i++)
{
    if ((arr[i] = (char *)malloc(v)) == 0)
    {
        // Out of memory — release what was already acquired
        for (size_t j = 0; j < i; j++)
             free(arr[i]);
        free(arr);
    }
}

そして、データを解放するために:

for (size_t i = 0; i < n; i++)
    free(arr[i]);
free(arr);

nどういうわけか、配列 (私のコード) 内の要素の数を追跡する必要があります。それを間違えることが問題です。他の順序で解放を行うことも同様です。要素の前にリリースarrするのは悪い間違いです。

からの戻り値をキャストするかキャストしないかについては、malloc()私に関する限り、あなた次第です。C++ はそれを要求します。malloc()C は、標準 C の前にそれを要求していました。呼び出す前に宣言する必要があるオプションを常に使用してコンパイルする限り、害はありません。C99 は、厳密な適合モードでそれを要求します。コンパイラに要求させます。私はほとんどの場合、厳密なコンパイラ オプションを使用して、それが確実に行われるようにします。

gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror ...

あなたがこれについてずさんな場合は、キャストしないでくださいmalloc()。気をつければ、気が向いたらキャストできます。

于 2013-11-10T21:51:22.497 に答える