何时删除try-catch块中的指针

时间:2017-07-06 19:21:27

标签: c++ pointers memory try-catch

快速最佳练习题(注意我不允许在此代码中使用任何智能指针)。我的印象是,如果我传递指向函数的指针并发生异常情况,那么如果在被调用函数或首次分配内存的函数中从未删除内存,则内存会泄露。删除catch块中的内存是否安全,还是应该删除调用函数中的内存?

示例:

int main() {
  object* myPtr = new object(); //dynamic memory on heap
  foo(*myPtr);  //pass pointer to function foo

  return 0;
}

void foo(object &pointer) {
  try {
    /* do stuff here
    with the pointer */
  }
  catch (const char &e) {
    cout<< "An error occured: " << e << endl;
  }
  catch (...)
    cout<< "Caught unknown exception." << endl;
  }
}

函数返回后我应该删除指针吗?

 int main() {
      object* myPtr = new object(); //dynamic memory on heap
      foo(*myPtr);  //pass pointer to function foo
      delete myPtr;

      return 0;
    }

或者在try-catch块中?

void foo(object &pointer) {
      try {
        /* do stuff here
        with the pointer */
      }
      catch (const char &e) {
        cout<< "An error occured: " << e << endl;
        delete &pointer;
      }
      catch (...)
        cout<< "Caught unknown exception." << endl;
        delete &pointer;
      }
    }

2 个答案:

答案 0 :(得分:5)

  

何时删除try-catch块中的指针

别。

在调用main之后,在foo中将其删除。

简而言之,在创建它的地方删除它。任何其他因素都会造成混乱的不对称。

  

我的印象是,如果我传递指向某个函数的指针并且发生异常情况,那么如果它永远不会被删除,则会泄漏内存。

不知道你在哪里听到的。算了吧。这是无稽之谈。

  

删除catch块中的内存是否安全,还是应该删除调用函数中的内存?

你可以:

  1. 删除trycatch
  2. 末尾的内存
  3. 在结束try / catch
  4. 之后删除内存

    两者都非常“安全”。

    但是,就像我说的那样 -

      

    我应该在函数返回后删除指针吗?

    是的,完全正确。

    顺便说一句

    您遗失了*和大写拼写错误:

    object* myPtr = new object();
    //    ^             ^
    

    实际上,带有智能指针的版本可能如下所示:

    #include <iostream>
    #include <memory>
    
    struct object {};
    
    void foo(object& obj)
    {
       try {
          // do stuff here with the reference (not a pointer)
       }
       catch (const char* e) {
          std::cout << "An error occured: " << e << std::endl;
       }
       catch (...)
          std::cout << "Caught unknown exception." << std::endl;
       }
    }
    
    int main()
    {
       auto myPtr = std::make_unique<object>();
       foo(*myPtr);
    }
    

答案 1 :(得分:3)

  

我的印象是,如果我将指针传递给函数并且发生异常情况,那么如果在被调用函数或首次分配内存的函数中从未删除内存,则内存会泄露。

不需要在分配内存的同一函数中释放内存。但是,是的,一般,如果指针指向分配有new的内存,那么如果永远不会调用delete,它就会泄露,无论在哪里这实际上是被称为。

  

删除catch块中的内存是否安全,还是应该删除调用函数中的内存?

在您的示例中,foo()没有关于如何分配object的概念,所以不,在delete内调用foo()是不安全的。

例如,您可以使用其中一个来调用foo(),如果foo()调用delete,则所有这些都会出现问题:

int main() {
    object myObj;
    foo(myObj);
    return 0;
}

int main() {
    std::unique_ptr<object> myPtr(new object);
    foo(*myPtr);
    return 0;
}

int main() {
    std::vector<char> buffer(sizeof(object));
    object *myPtr = new (&buffer[0]) object;
    foo(*myPtr);
    myPtr->~object();
    return 0;
}

foo的角度来看,object的分配方式并不重要,只要它是有效的object实例进入foo()。由于main()决定object的分配方式,main()应该是决定如何正确释放它的人(如果有的话)。