0

以下のコードでは、drvdClsから派生しbseClsます。このコードはそのままコンパイルおよび実行されます。ただし、ここで問題が見つかりました。終了newBse後に割り当てが解除されTest()ます。私は正しいですか?

bseCls* Test()
{

    bseCls* newBse = new drvdCls();
    drvdCls newDrvd;
    newBse = &newDrvd;
    return newBse;

}
4

2 に答える 2

4

が最初に指していたオブジェクトnewBseがリークされます。のアドレスをnewDrvd割り当てるnewBseと、ヒープ割り当てオブジェクトへのポインターが失われ、それができなくなりますdelete。このメモリは、プロセスが終了するまで使用できません。

さらに、スタックに割り当てられたオブジェクトのアドレスをポインターとして返していますが、これは次の 2 つの理由で問題があります。

  1. オブジェクトのデストラクタは、関数が戻る前に呼び出されます。つまり、破壊されたオブジェクトへのポインタを使用することになります。
  2. オブジェクトに割り当てられたメモリはスタック上に存在し、ほぼ確実に将来の関数呼び出しによって上書きされます。その時点で、ポインターは ではない何かを指しますがbseCls、それをあたかもそうであるかのように使用します。

この関数によって返されるポインターを使用すると、未定義の動作が発生し、プログラムには何でも実行できるライセンスが与えられます。

于 2013-03-21T16:09:02.087 に答える
1

いいえ、自動的に割り当て解除されることはありません。へのすべての呼び出しは、へnewの呼び出しと一致する必要がありますdelete。しかし、コードの問題はそれだけではありません。関数からローカル変数のアドレスも返しています。

newBse = &newDrvd; // memory leak, pointer to previously allocated object is lost
return newBse;     // newDrvd is destroyed when function exits, so returned
                   // pointer points to invalid memory

あなたがおそらくやりたいことは

bseCls* Test()
{
    return new drvdCls();
}

delete呼び出し元は、使用後に返されたポインターを呼び出す必要があります。あなたがすべきことは

std::unique_ptr<bseCls> Test()
{
    return new drvdCls();
}

返されたオブジェクトがスコープ外になると、割り当てられたオブジェクトは自動的にdeleted になります。unique_ptr

于 2013-03-21T16:09:12.863 に答える