快速最佳练习题(注意我不允许在此代码中使用任何智能指针)。我的印象是,如果我传递指向函数的指针并发生异常情况,那么如果在被调用函数或首次分配内存的函数中从未删除内存,则内存会泄露。删除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;
}
}
答案 0 :(得分:5)
何时删除try-catch块中的指针
别。
在调用main
之后,在foo
中将其删除。
简而言之,在创建它的地方删除它。任何其他因素都会造成混乱的不对称。
我的印象是,如果我传递指向某个函数的指针并且发生异常情况,那么如果它永远不会被删除,则会泄漏内存。
不知道你在哪里听到的。算了吧。这是无稽之谈。
删除catch块中的内存是否安全,还是应该删除调用函数中的内存?
你可以:
try
和catch
块try
/ catch
链两者都非常“安全”。
但是,就像我说的那样 -
我应该在函数返回后删除指针吗?
是的,完全正确。
您遗失了*
和大写拼写错误:
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()
应该是决定如何正确释放它的人(如果有的话)。