1

Valgrindを使用してcプログラムをデバッグしています。私が受け取るエラーは次のとおりです。

==2765== 8,000 bytes in 2 blocks are definitely lost in loss record 1 of 1
==2765==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==2765==    by 0x404123: main (mycode.cpp:352)

352行目付近のコードは次のとおりです。

int **matrix;
matrix = (int**)malloc(2*sizeof(int*));
for (i=0; i<2; i++){
    matrix[i] = (int*)malloc(size*sizeof(int)); //line 352
}
for (i=0; i<2; i++){ //inizialization
    for (k=0; k<size; k++)
        matrix[i][k] = 0;
}

これが、マトリックスにメモリを割り当てる私の方法です。これの何が問題になっていますか?


更新:プログラムの最後に、私は以下を使用しました:

free(matrix);
4

3 に答える 3

1

valgrindの出力は、メンバーを解放しているmatrixが、メンバーを解放していないことを示しています。free割り当てごとに1つの呼び出しが必要です。

for (i=0; i<2; i++) {
    free(matrix[i]);
}
free(matrix);

以下を使用してメモリを割り当てた場合、ゼロループへの初期化を回避して、コードを単純化できることに注意してくださいcalloc

int **matrix = malloc(2*sizeof(int*));
for (i=0; i<2; i++){
    matrix[i] = calloc(size*sizeof(int));
}
于 2013-02-27T10:23:00.153 に答える
1

なぜ人々は皆、配列の各行を別々に割り当てることを主張するのですか?1つの大きな割り当てとゲッター/セッターメソッドを作成するだけです!

#define ARR_COLUMNS 10
#define ARR_ROWS 10

int* arr = calloc (ARR_COLUMNS * ARR_ROWS, sizeof(int));

int get(int* arr, int x, int y) {
  if (x<0 || x>= ARR_COLUMNS) return 0;
  if (y<0 || y>= ARR_ROWS) return 0;
  return arr[ARR_COLUMNS*y+x];
}

void set (int* arr, int x, int y, int val) {
  if (x<0 || x>= ARR_COLUMNS) return;
  if (y<0 || y>= ARR_ROWS) return;
  arr[ARR_COLUMNS*y+x] = val;
}

そうすることで、次のようになります。

  • 費用のかかる割り当てと解放を節約する
  • 断片化されたメモリが少ない
  • 可能なrealloc呼び出しを単純化する
  • 一般的な[x][y]と[y][x]の反復キャッシュの問題なしに、データがより適切にキャッシュされ、アクセスされるようにします。
于 2013-02-27T10:24:38.970 に答える
1

simoncが言うように、個々の配列要素を解放していないように聞こえます。

可変長配列をサポートするC99コンパイラまたはC2011コンパイラを使用している場合は、少し単純化して、次のように単一mallocfree呼び出しを使用できます。

int size;
...
int (*matrix)[size] = malloc(2 * sizeof *matrix);
...
// do stuff with matrix[i][j]
...
free (matrix);

VLAをサポートしないコンパイラを使用している場合は、2段階の割り当てと割り当て解除を行うか、Dariusの回答のように1次元配列とマップインデックスを割り当てる必要があります。

于 2013-02-27T12:11:51.907 に答える