按值返回的内存管理差异
Memory management differences in return by value
我在这里学习一个教程:关于重载运算符,我发现了一些让我很困惑的东西。
在这个讨论本教程的网站上,之前有一个问题,即关于如何保留类中的变量,因为整个类都是按值传递的。
在尝试类定义时,我曾尝试过如下制作整数变量指针(也许不明智,但只是为了实验!(:
class CVector {
int* x;
int* y;
public:
CVector () {};
CVector (int,int);
CVector operator + (CVector);
~CVector ();
};
在类构造函数中,我为两个整数分配内存,在类解构器中,我删除分配的内存。
我还调整了过载操作员功能如下:
CVector CVector::operator+ (CVector param) {
CVector temp;
*temp.x = *x + *param.x;
*temp.y = *y + *param.y;
return (temp);
}
对于原始代码,如果类具有简单的整数变量,则整个类的按值返回成功完成。
然而,在我将变量更改为int指针后,由于整数变量不再完整,类的按值返回不会成功完成。
我假设当临时CVector超出范围并删除这些成员整数指针时,会调用解构器,但类本身仍然是按值返回的。
我希望能够在分配给其成员变量的内存完好无损的情况下按值返回CVector,同时确保临时CVector在超出范围时被正确删除。
有什么办法可以做到这一点吗?
非常感谢!
问题是你没有遵循这三者的规则,这基本上可以归结为:*如果你管理资源,那么你应该为你的类*提供复制构造函数、赋值运算符和析构函数。
假设在构造时为指针分配内存,问题是隐式复制构造函数是浅,并且将复制指针,但您可能想要深副本。在少数不需要深度副本的情况下,管理共享资源的控制会变得更加复杂,我会使用shared_ptr
,而不是尝试手动执行。
您需要为CVector
提供一个复制构造函数来复制分配的内存。否则,当您按值返回时,指针值将被简单地复制,然后temp
对象将被销毁,从而释放int。返回的副本现在指向无效内存。
CVector( const CVector& other )
: x ( new int(other.x) )
, y ( new int(other.y) )
{}
请注意,在类中使用原始指针是个坏主意,尤其是多个。如果y
的分配在上面失败,并且new
抛出,那么就出现了内存泄漏(因为x
处于悬空状态(。您可以在构造函数本身中进行分配,而不是在初始值设定项列表中,或者在try
-catch
中,或者使用new
的std::nothrow
版本,然后检查nullptr
。但是它使得代码非常冗长并且容易出错。
最好的解决方案是使用一些智能指针类,如std::unique_ptr
来保存指针。如果要使用std::shared_ptr
来保存这些指针,甚至可以在类的副本之间共享int。
按值返回会将返回的temp
对象复制到另一个对象,即临时"返回对象"。复制temp
后,它将被销毁,从而释放您的int。处理此问题的最简单方法是使用引用计数指针,如tr1::shared_ptr<>
。它将保留分配的内存,直到删除对它的最后一个引用,然后它将解除分配。
给定的代码中几乎没有问题。
(1( 您应该在构造函数中为*x
和*y
分配适当的内存;否则访问它们是未定义的行为。
CVector () : x(new int), y(new int) {}
还要确保在重新分配它们之前,在delete x
和delete y
的位置有复制构造函数和operator =
;否则会导致危险。
(2( delete
在析构函数中
~CVector () { delete x; delete y; }
(3( 通过const
引用将参数传递给operator +
,以避免不必要的复制。
CVector CVector::operator+ (const CVector ¶m)
{
// code
}
由于您正在学习指针,我不会对class
的设计视角发表评论,比如它们应该是指针、变量还是容器等等。
- 当vector是tje全局变量时,c++中vector的内存管理
- 当分配一个字符串值并稍后通过分配另一个值进行更改时C++如何管理内存?
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- 可以通过非原始指针来增强容器矢量管理内存
- 如何使用 std::vector<std::tuple<A,B>> 来管理内存(调整大小、保留,...),但实际上将 As 保留在 B 之前,连续
- 线程管理内存泄漏
- 通过读取文件创建映射<字符串,矢量>时如何管理内存<string>
- 管理内存C++
- ptr_vector如何管理内存
- 在C++Builder/Firemonkey中使用表单创建来管理内存
- 如何正确管理内存(运行时)C++
- 在Node.js中使用Native Abstractions时,如何管理内存
- ostream是如何管理内存的
- C++中管理内存泄漏的问题
- OpenCL:在 CPU 上而不是在 GPU 上更正结果:如何正确管理内存
- deque是如何管理内存的
- 用c++/cli互操作管理内存
- 如何衡量管理内存所花费的时间
- (加速C++)章节管理内存
- 如何在此场景中管理内存