次のコードがあるとします。
class Data
{
private:
int *m_arr;
int m_size;
bool m_deAlloc;
public:
Data(int *arr, int size): m_arr(arr), m_size(size), m_deAlloc(false) {}
~Data(){ if(m_deAlloc) delete[] m_arr; }
...
};
void foo(Data &d)
{
// uses d ...
}
void foo_wrapper(int *arr, int size)
{
Data d(arr, size); // should I create it as new Data(arr, size)?
foo(d); // asynchronous call...
} // ~Data() will be called but m_arr array will not be erased...
int main()
{
int *arr = new int[...];
...
foo_wrapper(arr,...); // internally calls foo asynchronously...
...
// wait for foo execution completion....
...
delete[] arr;
}
gccで試してみたところ、明らかに動作しますが、「foo_wrapper」から「foo」に渡された「Data」参照が無効になる可能性があるため、有効なプログラムではないと思います。渡されたオブジェクトのデストラクタは、fooの実行が完了する前に呼び出される可能性があります実行)。データ (m_arr) は削除しませんが、デストラクタが呼び出されるとオブジェクト参照はどうなりますか?
C++ (gcc) コンパイラはデストラクタを呼び出すだけですか。たとえば、オブジェクト「d」のデストラクタが呼び出された場合、オブジェクト「d」のメモリ割り当てを再配置し、「d」を無効な参照に設定しますか?