-4

私のコードではもう必要ないので、コードから削除するつもりです。しかし、そうするとsprintf()、セグメンテーション違反が発生しますが、ある場合sprintf()は正常に動作します。この理由とこれを解決する方法を教えてください問題。

unsigned char status_str[40]={0};
sprintf(status_str,"found HTTP:%dth time\n",(count+1));
4

2 に答える 2

1

まず、sprintf(3)の使用は非推奨です (少なくとも推奨されません。リンクされたマニュアル ページのBUGSセクションを参照してください)。これは危険な関数です (バッファ オーバーフローの可能性があるため)。snprintf(C99以降、つまり前世紀以降の標準です)とコードを代わりに使用する必要があります

snprintf (status_str, sizeof(status_str), 
          "found HTTP:%dth time\n", (count+1));

snprintfが望ましい理由はsprintf、出力がバッファをオーバーフローしてもsnprintf、指定されたサイズをオーバーフローしないのに対しsprintf、サイズ制限がわからない場合はオーバーフローするためです。

次に、sprintfセグメンテーション違反を回避した場合 (オーバーフローしないと仮定status_str)、プログラムの他の場所で未定義の動作 が発生したことになります。

sprintfおそらく、[スタックの場所] のいくつかの初期化されていない値を、たまたま後で機能させるもので満たすことを想像します。

-Wall -Wextra -g(警告が表示されなくなるまでコードを改善する) でコンパイルし、gdbデバッガーを使用することをお勧めします (そのwatchコマンドは役に立ちます)。valgrindまた、メモリ リーク (および初期化されいないアクセス)を探すために使用することもできます。

さらにヘルプが必要な場合は、さらにソース コードを表示してください。

GNU libc を使用すると、ヒープ化されたゾーンを割り当てて埋めるasprintfmallocを使用することもできます。この関数は GNU 固有です (そして、ポインターがfree-d 後であることを確認する必要があります)。

于 2013-05-03T12:10:04.383 に答える
1

セグメンテーション違反は正確にはどこですか?本当にそれを削除しただけで、コードが status_str を参照しなくなった場合は、スタックの破損を示している可能性があります。エラーは以前のどこかで発生する可能性があり、ランダムに動作しますが、スタック レイアウトが変更されると、コードの一見無関係な部分が明らかな理由もなく壊れる可能性があります。

例: 以前のコードがいくつかの値でスタックを上書きし、これらの値が status_str に達している場合、害はありませんが、それがなくなると、他の何かが上書きされ、これが segfault を引き起こす可能性があります。

それはただの推測です。そのため、特定の関数が呼び出される前に呼び出されるコードを確認する必要があります。

明確にするために:これが定義されている場所に応じて、必ずしもスタックではなく、任意のメモリにすることができます。

于 2013-05-03T12:11:53.953 に答える