-1

関数からローカルオブジェクトを返そうとしています

そして私はこの問題を抱えています

ローカルで作成されたオブジェクトを返すと、null が返されます

DString DString :: operator + (const char* param)
{
    // Variable definition
    int nSize = ( this->GetLength() + (strlen(param)));
// Create a new char array in the opropriate size
char* cstrNewString = new char[nSize + 1];

// Append data
strcpy(cstrNewString, this->_cstrString);
strcat(cstrNewString, (char*)param);
cstrNewString[nSize] = '\0';

// Create a new DString to return
DString dstNewData(cstrNewString);

// Clean up
delete[] cstrNewString;

// Return data
return (dstNewData); // Null!

次のような戻り行に新しいオブジェクトを作成するだけで、まったく同じことを行うと:

DString DString :: operator + (const char* param)
{
    // Variable definition


int nSize = ( this->GetLength() + (strlen(param)));

// Create a new char array in the opropriate size
char* cstrNewString = new char[nSize + 1];

// Append data
strcpy(cstrNewString, this->_cstrString);
strcat(cstrNewString, (char*)param);
cstrNewString[nSize] = '\0';

// Create a new DString to return
DString dstNewData(cstrNewString);

// Clean up
delete[] cstrNewString;

// Return data
return (DString(dstNewData.ToCharArray())); // Not null, returns correctly!

正しく返されます..なぜこれを行うのですか?どうすれば修正できますか?

4

4 に答える 4

3

コピーコンストラクタはどのように定義されていますか?最初のケースでは、コピーコンストラクターが呼び出されます。2番目の番号で。の必須コードは何も示していませんが、明らかなセマンティクスを考えると、コンパイラーが生成したコピーコンストラクターが 正しいことを行わないDStringことはほぼ確実のようです。デストラクタで削除される動的に割り当てられたポインタが含まれている場合(それ以外の場合はどうなるかわかりません)、コピーコンストラクタはディープコピーを作成する必要があります。DString

于 2012-09-18T13:16:36.917 に答える
1

最初のケースでは、(デフォルトの) コンストラクターを暗黙的に使用して値渡しします (定義していない場合は、DString::DString(char*).また、最適化によりさらに混乱が生じる可能性があるため、 Return Value Optimization (wikipedia)と Scott Meyers Effective C++ item 21 (末尾) も参照してください。制御されます。DString::DString(char const *)dstNewData.ToCharArray()

コンストラクターを実際に見ることなく、それは大げさな推測です。

于 2012-09-18T12:46:29.957 に答える
0

最初の関数は NULL を返さないと思いますが、返されたオブジェクトで ToCharArray() を呼び出すと NULL を返します。

これは、引数オブジェクトからthisオブジェクトに char バッファーをコピーする必要がある Copy コンストラクターをおそらく実装していないという事実に関連している可能性があります。

于 2012-09-18T12:58:40.877 に答える
0

いくつかのコメント: 1) cstrNewString にコピーする文字列の大きさと、それらが cstrNewString に収まるかどうかをどのように確認しますか?

2) strcpy() よりも strncpy() を優先してください -- strcpy を使用すると、配列のサイズを超えることができます。

3) 数行後に削除しただけなのに、なぜ new を使用しているのですか? 無料で割り当て解除されるスタックに割り当てます。(紐のほうがいいです)

4) cstrNewString[nSize] --> null が文字列の最後に配置されていることをどのように知ることができますか? 間にギャップはありますか?

于 2012-09-18T12:47:38.860 に答える