以下のコードでは、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();
}
返されたオブジェクトがスコープ外になると、割り当てられたオブジェクトは自動的にdelete
d になります。unique_ptr