AzP*_*AzP 10 c debugging valgrind memory-management
我正在开发一个小型的爱好项目(www.github.com/AzP/GLSL-Validate),我已经采用旧代码(过多的c和小c ++用于我自己的口味,但是,嘿,你能做什么? )我正试图在Linux和Windows上运行它.我有几次崩溃(现在有希望修复),但是自从我开始运行Valgrind以找到问题后,我一直想要解决我得到的抱怨.
我只是看不出这个代码有什么问题(除了在Valgrind投诉方面很难读出好看的"神奇数字").
我用以下命令运行Valgrind valgrind --track-origins=yes ./Program
291 //
292 // Malloc a string of sufficient size and read a string into it.
293 //
294 # define MAX_SOURCE_STRINGS 5
295 char** ReadFileData(char *fileName)
296 {
297 FILE *in = fopen(fileName, "r");
298 char *fdata;
299 int count = 0;
300 char**return_data=(char**)malloc(MAX_SOURCE_STRINGS+1);
301
302 //return_data[MAX_SOURCE_STRINGS]=NULL;
303 if (!in) {
304 printf("Error: unable to open input file: %s\n", fileName);
305 return 0;
306 }
307
308 // Count size of file by looping through it
309 while (fgetc(in) != EOF)
310 count++;
311
312 fseek(in, 0, SEEK_SET);
313
314
315 if (!(fdata = (char *)malloc(count+2))) {
316 printf("Error allocating memory\n");
317 return 0;
318 }
319 if (fread(fdata, sizeof(char), count, in) != count) {
320 printf("Error reading input file: %s\n", fileName);
321 return 0;
322 }
323 fdata[count] = '\0';
324 fclose(in);
325 if(count==0){
326 return_data[0]=(char*)malloc(count+2);
327 return_data[0][0]='\0';
328 OutputMultipleStrings=0;
329 return return_data;
330 }
331
332 int len = (int)(ceil)((float)count/(float)OutputMultipleStrings);
333 int ptr_len=0,i=0;
334 while(count>0){
335 return_data[i]=(char*)malloc(len+2);
336 memcpy(return_data[i],fdata+ptr_len,len);
337 return_data[i][len]='\0';
338 count-=(len);
339 ptr_len+=(len);
340 if(count<len){
341 if(count==0){
342 OutputMultipleStrings=(i+1);
343 break;
344 }
345 len = count;
346 }
347 ++i;
348 }
349 return return_data;
350 }
Run Code Online (Sandbox Code Playgroud)
这是Valgrind的输出.is 0 bytes inside a block of size 6 alloc'd我可以忽略它的意思吗?我的意思是'0字节'听起来不危险?但是既然我在这里发布了这个问题,我想你可以看到我认为我应该注意它.
==10570== Invalid write of size 8
==10570== at 0x401602: ReadFileData(char*) (StandAlone.cpp:335)
==10570== by 0x4013D8: CompileFile(char*, void*, int, TBuiltInResource const*) (StandAlone.cpp:255)
==10570== by 0x401016: main (StandAlone.cpp:152)
==10570== Address 0x5f627a0 is 0 bytes inside a block of size 6 alloc'd
==10570== at 0x4C2880D: malloc (vg_replace_malloc.c:236)
==10570== by 0x401475: ReadFileData(char*) (StandAlone.cpp:300)
==10570== by 0x4013D8: CompileFile(char*, void*, int, TBuiltInResource const*) (StandAlone.cpp:255)
==10570== by 0x401016: main (StandAlone.cpp:152)
==10570==
==10570== Invalid read of size 8
==10570== at 0x401624: ReadFileData(char*) (StandAlone.cpp:336)
==10570== by 0x4013D8: CompileFile(char*, void*, int, TBuiltInResource const*) (StandAlone.cpp:255)
==10570== by 0x401016: main (StandAlone.cpp:152)
==10570== Address 0x5f627a0 is 0 bytes inside a block of size 6 alloc'd
==10570== at 0x4C2880D: malloc (vg_replace_malloc.c:236)
==10570== by 0x401475: ReadFileData(char*) (StandAlone.cpp:300)
==10570== by 0x4013D8: CompileFile(char*, void*, int, TBuiltInResource const*) (StandAlone.cpp:255)
==10570== by 0x401016: main (StandAlone.cpp:152)
==10570==
==10570== Invalid read of size 8
==10570== at 0x40163F: ReadFileData(char*) (StandAlone.cpp:337)
==10570== by 0x4013D8: CompileFile(char*, void*, int, TBuiltInResource const*) (StandAlone.cpp:255)
==10570== by 0x401016: main (StandAlone.cpp:152)
==10570== Address 0x5f627a0 is 0 bytes inside a block of size 6 alloc'd
==10570== at 0x4C2880D: malloc (vg_replace_malloc.c:236)
==10570== by 0x401475: ReadFileData(char*) (StandAlone.cpp:300)
==10570== by 0x4013D8: CompileFile(char*, void*, int, TBuiltInResource const*) (StandAlone.cpp:255)
==10570== by 0x401016: main (StandAlone.cpp:152)
Run Code Online (Sandbox Code Playgroud)
编辑:我需要在c ++编译器中编译代码,这就是我必须保留所有演员阵容的原因malloc.
Omr*_*rel 15
这看起来不对:
char**return_data=(char**)malloc(MAX_SOURCE_STRINGS+1);
Run Code Online (Sandbox Code Playgroud)
应该是:
char **return_data = malloc ( (MAX_SOURCE_STRINGS+1) * sizeof *return_data );
Run Code Online (Sandbox Code Playgroud)
(为方便起见,增加了空间).
编辑:一些额外的解释:当你说return_data[i]=...你正在尝试写东西时return_data[i].现在,return_data是char**,return_data[i]是的char*.所以你正在将指针写入内存中的某个位置.
看起来您的指针长度为8个字节(很好),但您只分配了6个字节:MAX_SOURCE_STRING+1.所以有一个问题.
您尝试将其写入偏移0的事实并不重要 - 您仍然在尝试编写比缓冲区更多的数据,这就是valgrind所抱怨的.
要解决此问题,您应该分配足够的空间来容纳指针数组.每个指针都采用sizeof(char*),也可以写为sizeof(*return_data)或sizeof *return_data.所以总共应该分配n * sizeof *return_data字节,其中n(在你的情况下)是幻数6.
| 归档时间: |
|
| 查看次数: |
28265 次 |
| 最近记录: |