以下のコードでは、drvdClsから派生しbseClsます。このコードはそのままコンパイルおよび実行されます。ただし、ここで問題が見つかりました。終了newBse後に割り当てが解除されTest()ます。私は正しいですか?
bseCls* Test()
{
bseCls* newBse = new drvdCls();
drvdCls newDrvd;
newBse = &newDrvd;
return newBse;
}
以下のコードでは、drvdClsから派生しbseClsます。このコードはそのままコンパイルおよび実行されます。ただし、ここで問題が見つかりました。終了newBse後に割り当てが解除されTest()ます。私は正しいですか?
bseCls* Test()
{
bseCls* newBse = new drvdCls();
drvdCls newDrvd;
newBse = &newDrvd;
return newBse;
}
が最初に指していたオブジェクトnewBseがリークされます。のアドレスをnewDrvd割り当てるnewBseと、ヒープ割り当てオブジェクトへのポインターが失われ、それができなくなりますdelete。このメモリは、プロセスが終了するまで使用できません。
さらに、スタックに割り当てられたオブジェクトのアドレスをポインターとして返していますが、これは次の 2 つの理由で問題があります。
bseCls、それをあたかもそうであるかのように使用します。この関数によって返されるポインターを使用すると、未定義の動作が発生し、プログラムには何でも実行できるライセンスが与えられます。
いいえ、自動的に割り当て解除されることはありません。へのすべての呼び出しは、へ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