2

私は既存の c プロジェクト (sourceforge の spglib) に取り組んでおり、いくつかの配列の初期化をクリーンアップした後、次の問題が発生しています。

* glibc が検出されました * tests/spglibtest: free(): 次のサイズが無効です (高速): 0x08ab46e0 ***

バックトレースは次のとおりです。

#0  0xb7fe1424 in __kernel_vsyscall ()
#1  0xb5cfdd61 in raise () from /lib/libc.so.6
#2  0xb5cff5ee in abort () from /lib/libc.so.6
#3  0xb5d397ed in ?? () from /lib/libc.so.6
#4  0xb5d3f7b1 in ?? () from /lib/libc.so.6
#5  0xb5d4052b in ?? () from /lib/libc.so.6
#6  0xb5d441cd in free () from /lib/libc.so.6
#7  0xb6681484 in sym_get_multiplicity (cell=0xbfffe1f0, symprec=0.050000000000000003) at /git/xtalopt-public/src/spglib/symmetry.c:168
#8  0xb6680550 in spg_find_primitive (lattice=0xbfffe2a8, position=0x813c6f0, types=0x813c700, num_atom=2, symprec=0.050000000000000003)
    at /git/xtalopt-public/src/spglib/spglib.c:253

エラーは、以下の「free(trans)」行にあります。

int sym_get_multiplicity(const Cell *cell, const double symprec)
{
  int i, rc;
  double **trans;
  trans = (double**)malloc(cell->size * sizeof(double*));
  for (i = 0; i < cell->size; i++) {
    trans[i] = (double*)malloc(3 * sizeof(double));
  }

  rc = get_translation(&trans[0][0], identity, cell, symprec);

  for (i = 0; i < cell->size; i++) {
    free(trans[i]);
  }
  free(trans);

  return rc;
}

get_translation は次のように値を trans に割り当てます。

static int get_translation(double trans[][3], const int rot[3][3], const Cell *cell,
                           const double symprec)
{
...
  for (j = 0; j < 3; j++) {
    trans[num_trans][j] = someDouble;
  }
...
}

get_translation で配列に書き込むと、Valgrind は次のように表示されます。

==17929== Invalid write of size 8
==17929==    at 0x56BE8A7: get_translation (symmetry.c:285)
==17929==    by 0x56BE44B: sym_get_multiplicity (symmetry.c:163)
...
==17929==  Address 0x9cb5868 is 0 bytes after a block of size 8 alloc'd
==17929==    at 0x4024918: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==17929==    by 0x56BE3F7: sym_get_multiplicity (symmetry.c:158)
....

これは、trans に割り当てられたメモリの最後を超えて書き込もうとしているが、trans[0][0] に書き込んでおり、trans の次元が [2][3] であることを示唆しています。これはうまくいくはずです、AFAIK、私が見逃しているものを見ることができますか?

4

2 に答える 2

6

型が間違っています。配列の配列を期待する関数 (つまり、配列へのポインター) へのポインターの配列へのポインターを渡すことはできません。

get_translationあなたが持っている署名には、次のものが必要です。

double (*trans)[3] = malloc(cell->size * sizeof(double[3]));
于 2010-09-15T22:18:40.227 に答える
2

SO ここにおそらく 1 つの問題があります。あなたの関数は (に基づいて) trans[num_trans][j] = someDouble; を想定しているようです。そのtransは実際には順番に配置された配列であり、上で述べたように、この場合は当てはまりません。2 次元配列ではなく、ポインターの配列を割り当てています。に似たもの

double* トランス = malloc(セル->サイズ * 3); 良いかもしれません。一般に、2 次元配列の代わりに 1 次元配列を使用し、それを 2 次元配列として使用したい場合があります。

于 2010-09-15T22:25:59.680 に答える