2011-08-22 26 views
12

私はC++の文字列でかなり初心者ですので、次のパターンは少し醜いかもしれません。私は大規模なシステムとの統合テストを開始する前に、私が書いたいくつかのコードを見直しています。私が知りたいのは、それが安全かどうか、あるいはメモリを漏らす傾向があるかどうかということです。C++ std :: stringオブジェクトをメモリリークから安全に戻していますか?

string somefunc(void) { 
    string returnString; 
    returnString.assign("A string"); 
    return returnString; 
} 

void anotherfunc(void) { 
    string myString; 
    myString.assign(somefunc()); 
    // ... 
    return; 
} 

私は理解がReturnStringにの値が新しいオブジェクトのmyStringに割り当てられ、その後、ReturnStringにオブジェクトがsomefuncへの呼び出しを解決するの一環として、破壊されていることです。将来、myStringが範囲外になると、それも破壊されます。

私は通常、somefunc()にmyStringへのポインタを渡してmyStringの値に直接代入しましたが、私のコードで少し明確になるように努力しています。

+0

最初の関数では、おそらく "return string(" A string ");"同じ結果を持っています。 – luiscubal

+0

@luiscubalこれは問題を説明するための簡単な例です。 – Stephen

+2

@luiscubal even return "std :: stringはcの文字列で構成可能であるため、文字列"; "は正常です。 – log0

答えて

10

:それは完全に透明になりますさらに効率的です(空文字列の作成を省き、次の呼び出しで上書きされます。assign)。

std::stringは、独自のメモリを管理しており、コピーコンストラクタと代入演算子を正しく記述しているため、このように文字列を使用することは安全です。

2

はい、(少なくとも通常は)安全です。ほぼすべての合理的な文字列クラスの最も基本的な貢献の1つは、通常の割り当て、返品などが「うまくいく」基本的な値のように機能することです。あなたは、文字列のcopy constructorを呼び出している

return returnString 

を実行して、

7

はい。どの呼び出し式の「somefunc()」の代わりをすること(別名右辺値)一時的にReturnStringにの*コピーを実行します。

myString.assign(somefunc() /*somefunc()'s return becomes temporary*/); 

この順番に割り当てるために渡され、実行するために割り当てによって使用されていますmyStringにコピーします。

したがって、文字列のコピーコンストラクタはディープコピーを保証し、メモリリークを保証しません。

*これは真のディープコピーである場合とそうでない場合があることに注意してください。コピーコンストラクタの動作は実装固有です。いくつかの文字列ライブラリは、実際に必要となるまでコピーを防止するためにいくつかの内部簿記を持つコピーオンライトを実装しています。

+1

実際に、ディープコピーが実行されるかどうかは、使用している特定の標準ライブラリ実装に完全に依存します。 GCCはCOWを使用しているので、コピーコンストラクタは単純にカウンタをインクリメントすることを意味します。 –

+0

@Matthieu良い点私は私の答えを明らかにした。ありがとう。 –

5

文字列が値によって返されるため、完全に安全です。文字列は参照されずにコピーされます。 std::string &を返す場合は、間違ったことをしているでしょう。コンパイラの中には、戻り値の最適化を実行するものもあります。これは、実際には文字列を返しても実際にはコピーされません。詳細については、this postを参照してください。

0

文字列returnStringsomefuncの内部に作成され、関数が返されたときにコピーが返されると言っています。これは完全に安全です。

myStringsomefunc(ポインタは使用しないでください)への参照を指定します。これは読みやすいです

string myString = somefunc(); 

、および:はい、(値によって)stringこの方法を返すことは、私はそれをこのように割り当てることを好むだろうとはいえ、安全である

void somefunc(string& myString) { 
    myString.assign("A string"); 
} 

void anotherfunc(void) { 
    string myString; 
    somefunc(myString); 
    // ... 
    return; 
} 
+1

これはコンパイラによって一般的に実行される戻り値の最適化をバイパスします。 –

+0

@Bo Perssonパフォーマンスの向上について私は決して言わなかった。 – log0

+0

「あなたがしたいものは...」なぜそれを言うのですか?彼がやっていることに対して、あなたのコードにはほとんど利点がありません。 –

関連する問題