0

次のようなコードを見つけました(次のコードには多くの問題があります):

//setup consistent in each of the bad code examples
string someString; 
char* nullValue = getenv("NONEXISTENT"); // some non-existent environment variable  

// bad code example 1:
char x[1024];
sprintf(x," some text%s ", nullValue); //crashes on solaris, what about linux?  

// bad code example 2: 
someString += nullValue; // What happens here?  

//bad code example 3:
someString.append(nullValue); // What happens here?  

//bad code example 4:
string nextString=string(nullValue); //What happens here?
cout<<nextString;

私たちは、solaris、linux、gcc、sunstudio を使用しており、将来的には clang++ を使用する可能性が非常に高くなります。このコードの動作は、プラットフォームとコンパイラ全体で一貫していますか? 上記のコードのすべてのケースで予想される動作を説明する仕様を見つけることができませんでした。

現在、gcc を使用して (および Linux で) コードを実行する際に問題があります。上記のコードが原因でしょうか?

上記のコードがこれらすべての環境で同じように動作する場合、それは (動作がクラッシュであっても) 私にとって貴重な情報です。なぜなら、これが Linux の問題の原因ではないことがわかるからです。

4

3 に答える 3

2

一般に、有効なC文字列が期待される場合にこれらのNULLを使用すると、未定義の動作が発生します。これは、何かが発生する可能性があることを意味します。一部のプラットフォームは、このための動作を定義しようとします。IIRCには、%s形式の置換( "(null)"などの出力)のためにprintfファミリ関数にNULLポインタを渡すことを適切に処理するプラットフォームがあります。それ以外に、一部のプラットフォームは、そのような場合に再現可能なクラッシュ(致命的な信号など)を保証しようとします。しかし、一般的にこれに頼ることはできません。

コードのその領域に問題がある場合:はい、これは原因である可能性が高いか、他の原因を覆い隠す可能性があるため、修正してください。壊れています。

于 2013-01-19T22:06:23.820 に答える
1

最初に戻り値をチェックせずに、ポインタから文字列を構築する際に問題があります。getenv定義は次のように述べています。

名前が引数として指定された環境変数の値を含む C 文字列を取得します。要求された変数が環境リストの一部でない場合、関数はヌル ポインターを返します。

std::stringnull ポインターからを作成することは、C++ 標準では明示的に許可されていません。文字列に追加する場合も同様です ( +=)。

私は C の専門家でsprintfはありませんが、null ポインターを使用することも許可されていないという予感があります。

于 2013-01-19T22:00:55.663 に答える
1

説明したいずれかのケースで NULL ポインターを使用すると正確に何が起こるかは、「未定義の動作」です。一部の C ライブラリは、printf の文字列の NULL を認識し、"(null)" などを出力しますが、私は絶対にそれに依存しません。同様に、NULL の他の使用法は「未定義」です。つまり、さまざまなプラットフォームで特定の方法で機能しないことが保証されています。あるプラットフォームで発生することは、別のプラットフォームで発生することとはまったく異なる場合があります (または、コンパイラの別のブランド/バージョン、またはコンパイラの最適化設定が異なる場合、または運が悪い場合はその日の風がどのように吹くか)。この場合、クラッシュまたは「行儀の良いコード」につながる可能性があります。これは、C/C++ ライブラリの作成者によって異なります。

これらのいくつかがある場合の1つの解決策は、環境変数が設定されていない場合、NULLを返す代わりに空の文字列を返す[または「設定されていません」などの]「getenv_safe」を作成し、コードを直接、または#define getenv(x) getenv_safe(x).

于 2013-01-19T22:36:18.463 に答える