析构函数如何知道何时激活自身?它可以依靠吗?

Rob*_*son 3 c++ destructor memory-leaks

比方说,我有以下代码(纯例):

class a {
   int * p;
public:
   a() {
      p = new int;
   }
   ~a() {
      delete p;
   }
};

a * returnnew() {
   a retval;
   return(&retval);
}

int main() {
   a * foo = returnnew();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

在returnnew()中,在函数返回后(当retval超出范围时)会对retval进行破坏吗?或者它会在我返回地址后禁用自动销毁,我可以说删除foo; 在main()的末尾?或者,以类似的方式(伪代码):

void foo(void* arg) {
   bar = (a*)arg;
   //do stuff
   exit_thread();
}

int main() {
   while(true) {
      a asdf;
      create_thread(foo, (void*)&asdf);
   }
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

析构函数会去哪里?在哪里我要说删除?或者这是未定义的行为?唯一可行的解​​决方案是使用STL引用计数指针吗?这将如何实施?

谢谢 - 我已经使用了C++一段时间但从未遇到过这种情况,并且不想创建内存泄漏.

Bri*_*ndy 10

对于堆栈创建的对象,当对象超出范围时,将自动调用析构函数.

对于在堆上创建的对象,只有在显式调用时才会释放内存delete.

是否从函数返回堆栈创建对象的地址无关紧要.当项目超出范围时,仍将调用析构函数.

所以对于你的代码示例:

a * returnnew() 
{
   a retval;
   return(&retval);
}
Run Code Online (Sandbox Code Playgroud)

a在代码跳回到调用的代码之前调用析构函数returnnew().您返回该对象的地址,但该地址指向内存中不再属于您的位置.

在哪里我要说删除?

您只在使用 delete时使用new
您仅在使用delete[]时使用new[]

或者这是未定义的行为?

如何处理不属于您的内存地址将是未定义的行为.但这不是正确的代码.

唯一可行的解​​决方案是使用STL引用计数指针吗?

您可以按值返回对象,也可以在堆上创建新对象.您还可以通过参数将对象传递给函数,并要求函数更改它.

这将如何实施?

//Shows how to fill an object's value by reference
void fillA(a& mya) 
{
   mya.var = 3;
}

//Shows how to return a value on the heap
a* returnNewA() 
{
  //Caller is responsible for deleting the returned pointer.
  return new a();
}

//Shows how to return by value, memory should not be freed, copy will be returned
a returnA() 
{
  return a();
}
Run Code Online (Sandbox Code Playgroud)