Valgrind beschwert sich mit "Invalid write of size 8"
Arbeite ich an einem kleinen hobby-Projekt ( www.github.com/AzP/GLSL-Validate ), wo ich genommen habe alten code (zu viel c und wenig c++ für meinen eigenen Geschmack, aber hey, was kann man tun?) und ich versuche, es zu bekommen und läuft auf Linux und Windows. Ich hatte schon ein paar Abstürze (behoben, die nun hoffentlich), aber seit ich zu laufen begonnen Valgrind zu finden, die Probleme, ich blieb stecken mit dem Wunsch, zu beheben, die Beschwerden, die ich bekommen.
Ich kann einfach nicht sehen, was ist falsch an diesem code (außer, dass es ziemlich schwer zu Lesen mit schönen "magischen zahlen", die sich über die place) in Bezug auf die Valgrind-Beschwerden.
Ich bin mit Valgrind mit dem folgenden Befehl 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 }
- Und hier kommt die Valgrind-Ausgabe. Hat die is 0 bytes inside a block of size 6 alloc'd
bedeutet, dass ich es ignorieren? Ich meine, '0 bytes' klingt nicht gefährlich? Aber seit ich die Frage gepostet hier, ich denke, man kann sehen, dass ich denke, ich sollte darauf achten.
==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)
EDIT: ich brauche den code zu kompilieren in einem c++ - compiler, das ist, warum ich habe halten alle casts von malloc
.
- Vielleicht verfolgen Sie die Werte von
i
und sehen, wenn Sie jemals gehen über 5. - Meinst du 6, wie in MAX_SOURCE_STRINGS+1?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese falsch aussieht:
Sollte wohl sein:
(Leerzeichen Hinzugefügt, für die Bequemlichkeit).
BEARBEITEN: Einige Erklärungen:
Wenn Sie sagen
return_data[i]=...
Sie versuchen, etwas zu schreibenreturn_data[i]
. Jetztreturn_data
istchar**
, soreturn_data[i]
istchar*
. Also Sie schreiben einen Zeiger in einem bestimmten Ort im Speicher.Es sieht aus wie Ihre Zeiger sind 8 bytes lang ist (was in Ordnung ist), aber Sie haben nur die zugewiesenen 6 bytes:
MAX_SOURCE_STRING+1
. So gibt es ein problem.Die Tatsache, dass Sie versuchen, es zu schreiben, in offset 0 ist egal - du bist immer noch zu schreiben versucht, mehr Daten als der Puffer nehmen kann und das ist, was valgrind beschwert sich über.
Das problem zu lösen, sollten Sie genügend Speicherplatz für ein array von Zeigern. Jeder Zeiger
sizeof(char*)
, die kann auch geschrieben werden alssizeof(*return_data)
odersizeof *return_data
. Also insgesamt sollte man reservierenn * sizeof *return_data
bytes, won
ist (in deinem Fall) die Magische Zahl 6.malloc
weiß nichts über den Typen, er kennt nur bytes. So haben Sie, um berechnen Sie die Anzahl der bytes, die sich (die, als Sie entdeckt, ist nicht das gleiche wie die Anzahl der Artikel).