2011-10-05 4 views
8

と不平を言いますあなたはそうしていますか?)私はLinuxとWindowsでそれを稼働させようとしています。私はいくつかのクラッシュを覚えましたが(今はうまくいけば固定されています)、Valgrindを起動して問題を発見してから、私が苦情を修正したいと思っていました。Valgrindのは、私は古いコード(あまりにも多くのCと私自身の味のために少しのC++にを撮影した小さな趣味のプロジェクト(<a href="http://www.github.com/AzP/GLSL-Validate" rel="nofollow noreferrer">www.github.com/AzP/GLSL-Validate</a>)に取り組んでいますが、ちょっと、何ができるんだ「サイズ8の不正な書き込み」

私は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のを実行し、ここで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) 

編集:私はmallocのすべてのキャストを維持する必要があります理由です、C++コンパイラでコンパイルするコードが必要です。

+0

「i」の値を追跡し、5以上になるかどうかを確認してください。 –

+0

6 MAX_SOURCE_STRINGS + 1? – AzP

答えて

13

これは間違っているになります。

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

はおそらくあるべき:

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

(スペースは、便宜上追加されました)。

EDIT:いくつかの追加説明: あなたが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は(あなたの場合は)マジックナンバー6です。

+0

あなたの答えをありがとう!私はreturn_dataがchar *の配列であると解釈しました。これはchar配列の配列と考えることもできます。私は、mallocが6個のchar配列の配列を割り当てると考えました。次にコードは335行目で別のmallocを実行し、位置i(return_data [i])にサブ配列を割り当てます。たとえば、return_data [i] [0]などを使って配列に到達することができます。 – AzP

+0

しかし、あなたが言ったように、MALLOC_SOURCE_STRINGSを8に変更すると実際に苦情が取り除かれます。私が間違ってやっていることを理解し、それがあなたの情報に合っていると分かるまで、これを再考しなければならない=) – AzP

+0

ああ、私は今それを得ると思います。あなたはポインタに関する正しいです、私は6つのポインタが必要だと思った、そして彼らはそれぞれ1バイトを取った、もちろんそうではありません。 – AzP

関連する問題

 関連する問題