我一直在調試一個遺留代碼,運行在Linux上的XScale(arm v5te)系統,可重現崩潰。免費()無效指針 - 釋放指針陣列失敗
我已經用gdb調試和設置MALLOC_CHECK_爲1。這是一個很大的代碼,所以只是一些片段:
我們有這樣的結構:
typedef struct {
...clipped..
char **data_column_list;
/** data column count */
int data_column_cnt;
...clipped
} csv_t;
我們初始化函數列,把它們放在一個變量「列」
/* Allocating memory for pointer to every register id */
columns = (char **) malloc(column_cnt * sizeof(char *));
column_cnt = 0;
/* loop over all sensors */
for(i=0; i<cfg.sen_cnt; i++) {
/* loop over all registers */
for(j=0; j<cfg.sen_list[i]->data_cnt; j++) {
/* Storing all the pointers to id */
columns[column_cnt++] = cfg.sen_list[i]->data_list[j]->id;
}
}
在另一個功能,會發生什麼情況是這樣的:
/* free the previous list */
csv_free(lc_csv);
lc_csv->data_column_list = columns;
lc_csv->data_column_cnt = column_cnt;
csv_free之中:
void csv_free(csv_t *csv) {
if(csv->data_column_cnt > 0)
free(csv->data_column_list);
csv->data_column_cnt = 0;
}
現在,還有另外一個功能,構建整個 「CFG」/配置結構,包含這些ID。 上面的代碼:cfg.sen_list [i] - > data_list [j] - > id;其中cfg是一個結構體,sen_list是一個指向結構體的指針數組,data_list是指向其他結構體的指針數組,它包含一個字符串「id」。
當程序獲得SIGUSR1信號時,配置正在更新。所有這些data_list和sen_list結構都被釋放,然後生成新的結構。 然後使用第一個函數,生成新的id列,並將其放入csv結構中,但之前釋放舊列表。
這就是它崩潰的地方。在csv_free中。
*** glibc detected *** /root/elv: free(): invalid pointer: 0x0001ae88 ***
我以爲它應該是這樣的。你有一個指針數組。當你釋放指針時,你必須釋放指針,指向一組指針(數組)。 或把代碼而言,上述情況應模擬到:
char **ar = malloc(n * sizeof(char *));
char *xn = malloc(10 * sizeof(char)); // Do for 0 to n strings
...
ar[n] = xn; // Do for 0 to n strings
...do stuff...
free(xn); // Do for 0 to n strings
free(ar);
當結構,包含ID字符串,被釋放,我仍然有我的(無效)的指針,而不是空指針的指針數組:
(gdb) p csv
$40 = {sysid = 222, ip = '\0' <repeats 49 times>,
module = "elv_v2", '\0' <repeats 14 times>, format_type = 1, msg_id = 0,
data_column_list = 0x1ae88, data_column_cnt = 10, pub_int = 30,
line_cnt = 0, pub_seq = -1, format = 0x18260}
(gdb) p csv.data_column_list[0]
$41 = 0x1b378 "0"
但我得到上面的錯誤消息(或SIGABRT沒有MALLOC_CHECK_)。 我完全不明白這一點。我必須釋放這個指針數組,否則它會變成內存泄漏。之前沒有其他的免費電話,我可以找到。我不知道爲什麼csv.data_column_list被認爲是無效指針。 Valgrind是不幸的是沒有availiable上支持ARM v5TE :(
已經調試這幾個小時,並樂意的任何幫助 非常感謝你, 乾杯, 本
更新:
我想知道它是否可以連接到一些「範圍」問題。在另一個應用程序中有幾乎相同的代碼,它的工作原理是崩潰的函數「csv_free」被兩個程序使用(靜態鏈接)。唯一的區別是,包含要釋放的指針的結構通常在工作程序中聲明和定義,並聲明爲external
並在除main.c之外的其他文件中定義。 在main.c工作中手動調用「free」 「csv_free」崩潰。謎語我這個......
您是否嘗試用valgrind運行它? – 2012-03-16 15:23:13
如果你在mallocs之後,並且在釋放之前斷點,那麼所有的指針值是否匹配? – 2012-03-16 15:43:51
你應該檢查'csv'是'NULL'還是不在'csv_free'中,並且釋放'csv'後將它賦值爲NULL。當'csv'爲NULL或一些垃圾時,這將保護你免於'csv-> member'。 – phoxis 2012-03-16 15:57:37