I'm chasing down an segmentation fault with memory allocations, so I've decided to run my application with valgrind. At an unexpected location (but maybe relevant) I've run into "Invalid write of size 8". However, I do not see anything wrong with the code. I'd appreciate another set of eye on it.
I am not sure how much to provide, so here is the function in question.
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 has two interesting points of information:
==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==
So, I am using the sqlite3 library, and this callback function is building an array of the record set. Inside the array, is an array if the data, and that is the 'data' variable. I am doing something similar with col_name, but valgrind is okay with that and does not complain.