C++,这将导致内存泄漏
C++, will this cause memory leak?
我知道我无法获得本地变量的引用,例如:
int& func1()
{
int i;
i = 1;
return i;
}
我知道这是正确的,但我必须在调用func2((后删除它
int* func2()
{
int* p;
p = new int;
*p = 1;
return p;
}
int main()
{
int *p = func2();
cout << *p << endl;
delete p;
return 0;
}
如果函数是这样的:
MyClass MyFunction()
{
return new MyClass;
}
MyClass的整个定义是:
class MyClass
{
public:
MyClass() : num(1){}
MyClass(MyClass*) : num(10){}
int num;
};
这会导致内存泄漏吗?
我应该如何避免?函数返回的是一个对象而不是指针,那么我如何删除它呢
PS:代码来自《C++思考》一书第10章。原始代码为:
Picture frame(const Pictrue& pic)
{
// Picture has a constructor Picture(*P_Node)
// Frame_Pic derives from P_Node
// So the constructor Picture(*P_Node) will implicitly convert Frame_Pic to Picture.
return new Frame_Pic(pic);
}
MyClass MyFunction()
{
return new MyClass;
}
这实际上是错误的。您正在返回一个指针。所以应该是
MyClass* MyFunction()
如果你的函数是我上面提到的,如果你在使用后没有删除它,它会泄露内存。
我应该如何避免?函数返回的是一个对象而不是指针,那么我如何删除它呢
这是一个编译错误。所以删除它不会引起
如果删除从函数返回的指针,则不存在内存泄漏。然而,这很容易出错,因为这意味着函数的每个客户端都必须知道它应该删除返回值。使用智能指针(根据语义可以是shared_ptr
或unique_ptr
(的风格要好得多。
Picture
示例也是如此。如果这个对象正确地管理了它的资源(即在析构函数中删除,并且有一个好的复制构造函数和operator=
(根据三规则(,那么就没有内存泄漏。
使用更新的具有指针构造函数的MyClass
,我想您应该编写:
MyClass MyFunction() {
MyClass *ptr = new MyClass;
MyClass retval(ptr);
delete ptr; // the dynamically-allocated object isn't needed any more
return retval;
}
这恰好是异常安全的,因为MyClass的构造函数不能抛出,但作为一般规则,你真的不应该在不将结果直接放入智能指针的情况下调用new
:
MyClass MyFunction() {
std::unique_ptr<MyClass>(new MyClass);
return MyClass(ptr);
}
无论如何,这是一个相当荒谬的情况——如果你要按值返回,那么根本没有理由调用new
:
MyClass MyFunction() {
MyClass tmpvalue;
return &tmpvalue; // doesn't actually return the pointer, just an object
// constructed from it
}
由于指针的值甚至不被指针构造函数使用,您还可以写:
MyClass MyFunction() {
return 0; // returns an object constructed from a null pointer
}
在你引用的书中的原始代码中,我猜类Picture
有一个类型为P_Node*
的数据成员,它在其中存储指针值,并在其析构函数中对该指针调用delete
。希望作者也能对Picture
的复制构造函数和复制赋值运算符做些什么,以防止复制后出现双自由。我没有这本书,所以我不能检查我的猜测,但Picture
的代码应该显示它是如何完成的。
[编辑:哦,这是Koenig和Moo的书之一。他们(非常(有能力,所以他们的Picture
类可以正确地处理资源。如果没有,那是因为这是一个故意做错事的例子。]
这与您的"func2"示例相同。那些称之为"框架"的人最终需要释放返回的图片。
MyClass MyFunction()
{
return new MyClass;
}
是不正确的,因为运算符new返回指向MyClass的指针,但函数返回的是MyClass,而不是MyClass*
一个简单的检查是:
- 如果您在程序中使用
N
编号的new
,则必须在程序中采用N
编号的1delete
以避免内存泄漏2
你在这么做吗?是的,在第一种情况下(你在做new int
(,你不会这么做。没有内存泄漏。
帖子的其余部分对我来说还不够清楚!
1.通过兼容delete
,我的意思是,如果你以ptr = new T[M]
的形式使用new
,那么兼容的delete
应该是delete []ptr
的形式。类似地,delete ptr
与ptr = new T
兼容
2.当然,如果你使用一些智能指针,那么你不必显式地使用delete
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- 瓦尔格林德的内存泄漏使用新的
- 无法找出我的代码中的内存泄漏
- C++ 结构内部的unordered_map会导致内存泄漏问题吗?
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- Shared_ptr双链接列表内存泄漏
- C++ 在类中使用常量引用文本时 O2 内存泄漏