2010-09-15 48 views
2

我工作的一個現有的C項目(sourceforge上spglib),和我清理一些陣列初始化後運行到以下問題:*** glibc檢測到***免費():無效的下一個大小(快) - 應該工作?

* glibc的檢測*測試/ spglibtest:免費() :無效的下一個尺寸(快速):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 

的錯誤是在 「自由(反)」 下面一行:

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值分配給反像這樣:

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是dimension [2] [3]。這應該工作,AFAIK,任何人都可以看到我失蹤的東西?

+0

所以雖然不是答案,但trans與double trans [2] [3]定義的東西不完全相同。特別是在你的例子中,trans [0] [2]和trans [1] [0]並不是按順序放置在內存中的,對於類似dobule trans [2] [3]的東西來說,這是非常必要的。 – 2010-09-15 22:17:54

+0

您應該在調用get_translation()時獲得「不兼容指針類型傳遞的參數」警告 - 我建議調高編譯器警告級別。 – caf 2010-09-15 23:38:48

+0

真的不知道爲什麼這被標記爲重複。令人難以置信的通用錯誤消息是相同的,但潛在的問題是完全不同的...... – dlonie 2014-07-18 16:51:27

回答

6

您的類型錯誤,您無法將指針傳遞給期望數組數組(即指向數組的指針)的函數的指針數組。

對於你有get_translation簽名,您需要:

double (*trans)[3] = malloc(cell->size * sizeof(double[3])); 
+0

從內存管理的角度來看,這對我來說是有意義的,並且它在我做出更改時起作用 - 謝謝!然而,我在宣言中的語法方面遇到了一些麻煩,並且使用谷歌搜索沒有提供很多關於這方面的信息。你能推薦一個關於這種技術的參考嗎?再次感謝! – dlonie 2010-09-15 23:30:04

+0

@dlonie:關於這個問題的幾個最近的問題是:http://stackoverflow.com/questions/3707096/和http://stackoverflow.com/questions/3706704/。 – 2010-09-16 06:44:04

+0

啊,我現在看到了。我看到一個在聲明中被解除引用的指針而被拋棄了 - 根據我的C++經驗,這很不直觀!關於螺旋規則的提示幫助解決了這個問題。 – dlonie 2010-09-16 12:07:45

2

所以這裏可能是一個問題。你的函數似乎假設(基於)trans [num_trans] [j] = someDouble;這個trans實際上是一個按順序排列的數組,正如我上面提到的在這種情況下不是真的。您正在分配一個指針數組而不是2維數組。類似於

double * trans = malloc(cell-> size * 3);可能會更好。一般而言,您可能想使用1d數組而不是2d數組,並將其用作2維數組。

相關問題