我知道我无法获得本地var的引用。如:
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:代码来自“Ruminations on 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);
}
答案 0 :(得分:3)
MyClass MyFunction()
{
return new MyClass;
}
这实际上是错误的。你正在返回一个指针。 所以它应该是
MyClass* MyFunction()
如果你的功能如上所述,如果你在使用它之后没有删除它。它会泄漏内存。
我应该如何避免它?该函数返回一个对象而不是一个指针,那么如何删除它呢?
这是一个编译错误。所以删除它的点不会上升
答案 1 :(得分:2)
如果删除从函数返回的指针,则没有内存泄漏。但是这很容易出错,因为这意味着函数的每个客户端都必须知道它应该删除返回值。根据语义使用智能指针(shared_ptr
或unique_ptr
)会更好。
同样适用于Picture
示例。如果此对象正确管理其资源(即在析构函数中删除并具有良好的复制构造函数和operator=
(根据Rule of Three),则没有内存泄漏。
答案 2 :(得分:1)
使用具有指针构造函数的更新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
的代码应该显示它是如何完成的。
Picture
类正确处理资源。如果没有,那是因为它是故意做错的一个深思熟虑的例子。]
答案 3 :(得分:0)
这是一个简单的检查:
N
个new
个数,那么您必须使用N
个兼容 1 <程序中的/ sup> delete
以避免内存泄漏 2 。new int
),你就是这样做的。没有内存泄漏。
其余的帖子对我来说还不够明确!
1。通过兼容 delete
,我的意思是如果您以new
的形式使用ptr = new T[M]
,则兼容的delete
应为delete []ptr
。同样,delete ptr
与ptr = new T
兼容。
2。当然,如果您使用的是智能指针,那么您不必明确使用delete
。
答案 4 :(得分:0)
它与你的“func2”示例相同。谁曾经称之为“框架”,最终需要释放返回的图片。
答案 5 :(得分:0)
MyClass MyFunction()
{
return new MyClass;
}
是不正确的,因为operator new返回一个指向MyClass的指针,但是你的函数返回MyClass,而不是MyClass *