2011-01-26 9 views
1

このコードは大丈夫ですか?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はわかりませんか?

+2

WTF o_O。 'const char *'を 'std :: string'に変換して' const char * 'に戻します。何のために地球上で? – mingos

+0

@mingos:文字列を作成して 'c_str()'を抽出すると、明示的にバッファを割り当てなくても何らかの形でコピーが行われるかもしれないと思って、一時期のようなものの範囲や生存期間に関する不確実性のため、 strcpyを呼び出します。それは、初心者のC++プログラマーのための完全に合理的な、そして一般的な間違いです。 –

+0

@Marcelo:OK、私はそのような可能性を考慮しなかった。 – mingos

答えて

6

コンパイルされており、未定義の動作が発生しないため、問題はありません。

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; 
} 
2

をあなたはnameで何もしない場合、それは完全に安全です。さもなければ、それはおそらく未来のあるランダムな時点で失敗するでしょう。 c_str()メンバ関数によって返されたCスタイルのポインタは、std::stringが一時的に存在している限り(およびこの場合は変更していない限り)有効です。囲みブロックスコープが終了するとすぐに、一時的なものは破壊され、nameを使用すると、あなたは夕暮れゾーンに入ります。

他の人も示唆しているように、namestd::stringにする必要があります。あるいは、もしあなたが本当にchar *のままにする必要があれば、name = strdup(_name)と書くことができます。

3

それを使用しても問題ありません。一時的にメモリが解放されるとすぐに解放されます。なぜ文字列をメンバーとして使用しないのですか?それでは、メモリ管理について心配する必要はありません。

1

この場合、一時オブジェクトを作成してポインタに割り当てます。関数を終了すると、このオブジェクトは破棄され、ポインタはどこにも指していません。 メモリがまだ上書きされていないため、場合によっては動作する可能性があります。しかし、この問題を避けるためにstrcpyを使うべきです。

+0

一時オブジェクトは、完全な式の最後で破棄され、関数の最後では破棄されません。 –

0

私はstrcpyに投票しました。なぜ単純なことを複雑にするのですか?

また、後で使用する必要があるため、std::stringに変換してから使用してください。それ以降はすべてchar *を忘れてしまいます。

関連する問題