このコードは大丈夫ですか?std :: stringコンストラクタを使用したconst char *のコピー
void SomeClass :: foo(const char * _name) {
//name is of type const char *
name = std::string(_name).c_str();
}
それが働いているように見えますが、それがOKであれば
iは古い学校のstrcpyを行う必要がありIAMはわかりませんか?
このコードは大丈夫ですか?std :: stringコンストラクタを使用したconst char *のコピー
void SomeClass :: foo(const char * _name) {
//name is of type const char *
name = std::string(_name).c_str();
}
それが働いているように見えますが、それがOKであれば
iは古い学校のstrcpyを行う必要がありIAMはわかりませんか?
コンパイルされており、未定義の動作が発生しないため、問題はありません。
OKステートメントが実行を完了した後に名前が無効なメモリを指しているため、okです。
name = std::string(_name).c_str();
このステートメントの最後に、一時的なstd :: stringが破棄され、c_str()のメモリが解放されます。
私は古い学校のstrcpyを行う必要がありますか?
いや、ただのstd ::文字列であることを名前を変更します。
void SomeClass :: foo(const char * _name) {
//name is of type std::string
name = _name;
}
をあなたはname
で何もしない場合、それは完全に安全です。さもなければ、それはおそらく未来のあるランダムな時点で失敗するでしょう。 c_str()
メンバ関数によって返されたCスタイルのポインタは、std::string
が一時的に存在している限り(およびこの場合は変更していない限り)有効です。囲みブロックスコープが終了するとすぐに、一時的なものは破壊され、name
を使用すると、あなたは夕暮れゾーンに入ります。
他の人も示唆しているように、name
をstd::string
にする必要があります。あるいは、もしあなたが本当にchar *
のままにする必要があれば、name = strdup(_name)
と書くことができます。
それを使用しても問題ありません。一時的にメモリが解放されるとすぐに解放されます。なぜ文字列をメンバーとして使用しないのですか?それでは、メモリ管理について心配する必要はありません。
この場合、一時オブジェクトを作成してポインタに割り当てます。関数を終了すると、このオブジェクトは破棄され、ポインタはどこにも指していません。 メモリがまだ上書きされていないため、場合によっては動作する可能性があります。しかし、この問題を避けるためにstrcpyを使うべきです。
一時オブジェクトは、完全な式の最後で破棄され、関数の最後では破棄されません。 –
私はstrcpy
に投票しました。なぜ単純なことを複雑にするのですか?
また、後で使用する必要があるため、std::string
に変換してから使用してください。それ以降はすべてchar *
を忘れてしまいます。
WTF o_O。 'const char *'を 'std :: string'に変換して' const char * 'に戻します。何のために地球上で? – mingos
@mingos:文字列を作成して 'c_str()'を抽出すると、明示的にバッファを割り当てなくても何らかの形でコピーが行われるかもしれないと思って、一時期のようなものの範囲や生存期間に関する不確実性のため、 strcpyを呼び出します。それは、初心者のC++プログラマーのための完全に合理的な、そして一般的な間違いです。 –
@Marcelo:OK、私はそのような可能性を考慮しなかった。 – mingos