2013-01-14 88 views
4

我追查內存分配的分段錯誤,所以我決定用valgrind運行我的應用程序。在意想不到的位置(但也許是相關的),我遇到了「無效的8號寫入」。但是,我沒有看到代碼有任何問題。我會欣賞另一組眼球。valgrind報告「無效的寫入大小8」

我不知道要提供多少,所以這裏是有問題的功能。

43 static int sql_callback(void *sql_record, int argc, char **argv, char **azColName){ 
44 int i; 
45 SQL_INFO *sql_info; 
46 void *sql_temp; 
47 sql_info = (SQL_INFO *)sql_record; 
48 
49 
50 sql_info->num_cols=argc; 
51 
52 sql_info->sql_data=(SQL_DATA**)realloc(sql_info->sql_data,(sql_info->num_rows+1)*sizeof(SQL_DATA *)); 
53 sql_info->sql_data[sql_info->num_rows]=calloc(1,sizeof(SQL_DATA *)); 
54 
55 sql_info->sql_data[sql_info->num_rows]->col_name=calloc(1,sizeof(*azColName)*argc); 
56 sql_info->sql_data[sql_info->num_rows]->data=calloc(1,sizeof(*argv)*argc); 
57 
58 for(i=0; i<argc; i++){ 
59  sql_info->sql_data[sql_info->num_rows]->col_name[i]=strdup(azColName[i]); 
60  sql_info->sql_data[sql_info->num_rows]->data[i]=strdup(argv[i]); 
61 } 
62 sql_info->num_rows++; 
63 return 0; 
64 } 

Valgrind的有兩個信息有趣的點:

==31925== Invalid write of size 8 
==31925== at 0x405EC2: sql_callback (sql.c:56) 
==31925== by 0x5310FF5: sqlite3_exec (in /usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6) 
==31925== by 0x4060D6: sql_query (sql.c:87) 
==31925== by 0x405121: send_trip_record (ssl_main.c:573) 
==31925== by 0x404579: do_work (ssl_main.c:380) 
==31925== Address 0x70f0fc8 is 0 bytes after a block of size 8 alloc'd 
==31925== at 0x4C29DB4: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==31925== by 0x405E8D: sql_callback (sql.c:53) 
==31925== by 0x5310FF5: sqlite3_exec (in /usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6) 
==31925== by 0x4060D6: sql_query (sql.c:87) 
==31925== by 0x405121: send_trip_record (ssl_main.c:573) 
==31925== by 0x404579: do_work (ssl_main.c:380) 
==31925== 

所以,我現在用的是sqlite3的庫,而這個回調函數正在建設的記錄集的數組。在數組內部,是一個數組,如果是數據,那就是'數據'變量。 我正在做一些與col_name類似的事情,但valgrind可以,並且不會抱怨。

回答

11

在這一行:

53 sql_info->sql_data[sql_info->num_rows]=calloc(1,sizeof(SQL_DATA *)); 

你應該不是分配sizeof(SQL_DATA)

因爲在第二天的語句,你開始訪問sql_info->sql_data[sql_info->num_rows]就好像它是一個SQL_DATA對象:

55 sql_info->sql_data[sql_info->num_rows]->col_name=calloc(1,sizeof(*azColName)*argc); 
56 sql_info->sql_data[sql_info->num_rows]->data=calloc(1,sizeof(*argv)*argc); 
+1

這正是Valgrind的抱怨。您可以通過在被分配給變量的變量上使用'sizeof'來避免這種類型的錯誤,而不是使用命名類型''calloc(1,sizeof * sql_info-> sql_data [0])' – caf

+0

ugh。對。分配數據的大小,而不是指針的大小。我也在52號線上做了修改,清理了它。看起來我仍然有我的seg故障,但至少這是明確的。謝謝。 – jgauthier