簡體   English   中英

Valgrind抱怨“寫入8號無效”

[英]Valgrind complains with “Invalid write of size 8”

我正在開發一個小型的愛好項目( 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 }

這是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)

編輯:我需要在c ++編譯器中編譯代碼,這就是為什么我必須保留malloc所有演員。

這看起來不對:

char**return_data=(char**)malloc(MAX_SOURCE_STRINGS+1);

應該是:

char **return_data = malloc ( (MAX_SOURCE_STRINGS+1) * sizeof *return_data );

(為方便起見,增加了空間)。

編輯 :一些額外的解釋:當你說return_data[i]=...你試圖寫一些東西到return_data[i] 現在, return_datachar** ,所以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 * sizeof *return_data字節,其中n是(在你的情況下)幻數6。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM