0

以下にこのコードスニペットがありますが、動的割り当てである「str」での割り当て中にクラッシュします。

  char *str;
  int file_size;
  FILE *fptr;
  if (!(fptr = fopen(filename, "r"))) goto error1;
  if ((fseek(fptr, 0L, SEEK_END) != 0)) goto error2;
  if (!(file_size=ftell(fptr))) goto error2;
  if ((fseek(fptr, 0L, SEEK_SET) != 0)) goto error2;
  str =  (char*)malloc(file_size+1);
  if (fread(str, file_size, 1, fptr) != 1) {
    free(str);
    goto error2;
  }
  str[file_size] = '\0';
  fclose(fptr);

file_sizeはゼロ以外、負ではない140未満の値

ARMを使用しています。これは実際には私のIntelPCで機能しますが、アームマシンでは機能しません。

4

7 に答える 7

7

これはマニュアルで確認できます。ftell()はエラー時にゼロではなく-1を返します。

于 2009-06-05T09:17:54.413 に答える
3

file_size変数を使用する前に、特に変数を印刷してください。あなたは驚きを得るかもしれません。

于 2009-06-05T09:18:39.340 に答える
2

によって返される値は何ftell(fptr)ですか?多分それは大きすぎますか?それが実際にlongintを返す場合、それはあなたのintをオーバーフローする可能性があり、そこで負の値を取得します。

于 2009-06-05T09:19:36.000 に答える
2

mallocは、引数にsize_tを予期しています。size_tは、unsignedintまたはunsignedlong(プラットフォームによって異なります)のtypedefであり、ここでのキーはUNSIGNEDです。

file_sizeにintを使用していて、intはちょうど16ビットである可能性があります(ARMを使用しているので、これはMCUだと思います)。符号付き16ビットはバイト単位で32,768バイトのファイルサイズしかサポートできないため、大きなファイル(実際にはそれほど大きくない、ちょうど> 32K)がある場合、file_sizeはオーバーフローします。

コンパイラはそれを教えてくれたと思いますが、あなたはそれを無視することを選択します...今やmallowは符号なしの引数を取るので、filesize + 1の符号付き評価を自動的にキャストします(深くオーバーフローした場合でも、符号付きの大きな時間は負です)。メモリを割り当てます。これは、この組み込みアプリよりもはるかに多くのメモリを割り当てようとしたことを意味している可能性があります。持つことはできません(クラッシュするべきではありませんでした)。

クラッシュの理由は実際にはわかりませんが(ユーザーベースのフィードバックが少ないため、組み込みCでは一般的な悪いライブラリを除いて)、望ましくない動作につながるエラーが表示されます。

私は行って「なぜ後藤のものなのか」と尋ねることさえしません。なぜなら、答えは多くの炎のコメントを引き起こすからです。

于 2009-06-05T10:23:41.677 に答える
1

不適切なアドレスでバッファオーバーフローまたはfree()を実行する前のどこか!!!-)

于 2009-06-05T10:37:25.377 に答える
0

一般的な意味で...私はbashするつもりはまったくありませんが、あなたのコードは少しひどいです。コーディング標準を使用すると、通常、物事がはるかに明確になります...とはいえ、ニールはおそらく答えを得ました。

于 2009-06-05T10:07:01.740 に答える
0

これがあなたの問題である可能性は低いですが、覚えていましたか

#include <stdlib.h>

malloc のプロトタイプがスコープ内にあるように?この場合、戻り値が無償でキャストされるため、コンパイラは警告しません。C では、malloc の戻り値をキャストする理由はありません。そう:

str =  malloc(file_size + 1);

ちなみに、空白は自由です。

最後に、複数のプラットフォームでこの方法でサイズを推測できるようにする場合は、ファイルをバイナリ モードで開く必要があります。

に基づく:

str[file_size] = '\0';

ファイルに \0 文字を埋め込むことはできないと暗黙のうちに想定しているようです。あなたが本当にそれを作っているのなら、それは危険な仮定のように私には思えます.

于 2009-06-05T11:27:20.907 に答える