*** glibc 检测到 *** free(): 下一个大小无效(快)——应该可以吗?
我正在开发一个现有的c项目(sourceforge上的spglib),在清理一些数组初始化后遇到以下问题:
* glibc检测到*测试/ 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,有人能看到我丢失的东西吗?
I'm working on an existing c project (spglib on sourceforge), and I'm running into the following problem after cleaning up some array initializations:
* glibc detected * tests/spglibtest: free(): invalid next size (fast): 0x08ab46e0 ***
The backtrace is:
#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
The error is in the "free(trans)" line below:
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 assigns values to trans like so:
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;
}
...
}
Valgrind is showing the following when writing to the array in get_translation:
==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)
....
This suggests to me that it's trying to write past the end of the allocated memory for trans, but it's writing to trans[0][0], and trans is of dimension [2][3]. This should work, AFAIK, can anyone see something that I'm missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的类型是错误的,您无法将指向指针数组的指针传递给需要数组数组的函数(即指向数组的指针)。
对于您拥有的
get_translation
签名,您需要:Your types are wrong, you can't pass a pointer to an array of pointers to a function expecting an array of arrays (i.e. a pointer to an array).
For the signature of
get_translation
that you have, you need:所以这也许是一个问题。您的函数似乎假设(基于) trans[num_trans][j] = someDouble; trans 实际上是一个按顺序排列的数组,正如我上面提到的,在这种情况下是不正确的。您正在分配一个指针数组而不是一个二维数组。类似于
double* trans = malloc(cell->size * 3);可能会更好。一般来说,您可能想使用一维数组而不是二维数组,并将其用作二维数组。
SO here is perhaps one problem. Your function seems to assume (based on) trans[num_trans][j] = someDouble; that trans is in fact an array laid out sequentially which as I mentioned above is not true in this case. You are allocating an array of pointers rather than a 2 dimensional array. Something similar to
double* trans = malloc(cell->size * 3); might be better. In general you might want to use a 1d array instead of a 2d one and just use it as 2 dimensional array.