0

私はグローバルな構造を持っています:

struct thread_data{
   char *incall[10];
   int syscall arg_no;
   int client_socket;
};

そしてmain()で

char buffer[256];
char *incall[10];
struct thread_data arg_to_thread;

strcpy(incall[0],buffer);   /*works fine*/
strcpy(arg_to_thread.incall[0],buffer); /*causes segmentation fault*/

なぜこれが起こるのですか、そして解決策を提案してください。

ありがとう

4

3 に答える 3

5

セグメンテーション違反は、何かが間違っていることを意味します。しかしセグメンテーション違反がないということは、何か間違っていないという意味ではありません。2つの状況が基本的に同じで、一方のセグメンテーション違反ともう一方の状況が同じでない場合、通常は両方が間違っていることを意味しますが、たまたまどちらか一方だけがセグメンテーション違反をトリガーしています。

行を見ると、char* incall[10]それは、charへの10個のポインターの配列があることを意味します。デフォルトでは、これらのポインタはランダムな場所を指しています。したがって、incall [0]に入ると、文字列がランダムな場所にコピーされます。これはおそらくセグメンテーション違反になりそうです!最初にincall[0]を初期化する必要があります(を使用してmalloc)。

それで、より大きな問題は、なぜ最初の行がセグメンテーション違反にならないのかということです。その理由は、以前にメモリにあったものがすべて有効なポインタであったためだと思います。したがって、strcpyはセグメンテーション違反ではなく、後で完全に予期しない動作を引き起こす他の何かを上書きするだけです。したがって、両方のコード行を修正する必要があります。

もう1つの問題(一度修正すると)は、strcpyそれ自体が非常に危険であるということです。0バイトが見つかるまで文字列をコピーして停止するため、コピーする量を正確に確認することはできません(strlen割り当てに使用しない限り)。宛先メモリ)。したがってstrncpy、代わりにを使用して、コピーされるバイト数をバッファのサイズに制限する必要があります。

于 2011-06-09T06:03:47.187 に答える
1

ポインタを初期化していないので、goodnessは最初の書き込みincall[0]先しか知りません。strcpy()プログラムがすぐにクラッシュしないのは不幸です。

ポインタarg_to_thread.incall[0]を初期化していないので、goodnessは2番目がどこにstrcpy()書き込むかしか知りません。プログラムが後でではなく、今すぐクラッシュするのは幸運です。

どちらの場合も、それはコンパイラのせいではありません。ポインタを初期化することを常に確認する必要があります。

于 2011-06-09T06:00:43.650 に答える
0
  1. 文字列バッファに十分なメモリが割り当てられていることを確認してください。
  2. から離れてstrcpyください。strncpy代わりに使用してください。strcpyは、バッファオーバーフローの脆弱性の悪名高い原因です。これは、セキュリティとメンテナンスの悪夢であり、言い訳にはなりません。
于 2011-06-09T06:01:37.083 に答える