【问题标题】:Freeing a pointer from another function从另一个函数中释放指针
【发布时间】:2011-03-28 11:50:17
【问题描述】:

给定代码:

#include<iostream>
using namespace std;

class String
{
      char *pstr;
      unsigned size;
      public:
             String(){ pstr=0;size=0;}
             String(const char *);
             void show(){ cout << pstr << endl ; }
             ~String () { cout << "In Dtor" << endl; delete [] pstr; }

};

String::String(const char * cptr)
{
    size = strlen (cptr) + 1;
    cout << "String is - " << cptr << " - of size " << size - 1 << endl ;
    pstr = new char [ size ] ;
    for ( int i = 0 ; i < size ; i++)
        pstr[ i ] = cptr [ i ];

}



int main()
{
    String s("Hello World");
    s.show();
    s.~String();
}

输出:

    String is - Hello World - of size 11
    Hello World
    In Dtor
----Debug Assertion Failure----
    In Dtor

为什么要再次调用析构函数?我什么时候调用了析构函数?

什么是断言失败?

此代码也有效吗?

char * ptr=0;    

 void fun()
 {
      const char * p = "Hello World";
      int size = strlen(p )+ 1;
      cout << size << endl;
      ptr = (char *)malloc(size);
      for ( int i = 0 ; i < size ; i++)
      ptr[ i ] = p [ i ];
      cout << p << endl << ptr << endl ;
 }

int main()
{
    fun();   
    free (ptr); --> Note
}

可以从另一个函数中释放指针吗?这是我想在这里理解的主要内容。

【问题讨论】:

  • 不需要显式调用析构函数,您没有使用免费存储。
  • @DumbCoder:即使使用堆,您也不会显式调用析构函数。你只打电话给delete
  • @Acme:在您的编辑中:是的,您可以,但这并不真正属于同一个问题。另外,我确定之前已经回答过:先搜索再询问!
  • @Xeo::如果一切都可以搜索,就不需要 StackOverflow。您认为 SO 是您获得答案的唯一地方吗?
  • @Acme:搜索 SO 本身当然是一种选择……但除此之外。它并不真正属于这个问题。如果尚未提出(或者您找不到类似问题),则将其作为一个新问题提出,以便可以搜索它。 ;)

标签: c++ visual-c++ function string destructor


【解决方案1】:

您不应该手动调用析构函数 - 当 s 在最后的 '}' 超出范围时调用它

断言失败意味着名为assert(somecondition) 的东西和某些条件为假。这是一种用于验证您的假设的技术 - 如果您的代码依赖于某些特定条件为真,并且除非您有错误,否则该条件确实应该为真,那么您插入一个断言。

然后您可以选择在启用断言的情况下进行编译 - 这意味着如果您的假设错误,您将收到这样的错误。对于发布版本,您通常会禁用断言 - 不会为断言语句生成代码,也不会产生额外的运行时成本。

在某些情况下手动调用析构函数是正确的 - 在您了解并使用“placement new”之前,您将不需要它。

【讨论】:

  • +1 - 澄清:析构函数被手动调用一次,然后当s 超出范围时再次被调用。
【解决方案2】:

除了 Erik 已经说过的话:

删除手动析构函数调用后,您的代码仍然容易被双重删除:您必须禁用复制构造函数/赋值运算符,或正确实现它们(如果您坚持拥有堆分配的内存,则需要引用计数)。

【讨论】:

  • 这应该是个评论吧? :)
猜你喜欢
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多