构造函数对象赋值是否泄漏内存
Do constructor object assignments leak memory
假设我有一个简单的类,如下所示:
class MyObj
{
char* myPtr;
public:
MyObj()
{
myPtr = malloc(30);
}
~MyObj()
{
free(myPtr);
}
}
class TestObject
{
MyObj _myObj;
public:
TestObject(MyObj myObj)
{
_myObj = myObj;
}
};
这会泄漏内存吗?我的理由是,在构造函数运行时,TestObject 中已经包含一个 MyObj 实例,那么在释放内存之前,这不会吹走 myPtr 吗?分配给本地对象是否会调用被替换对象的析构函数?如果对象实例变量直接在构造函数中赋值,编译器是否会优化对象实例变量的赋值?我来自 C#,其中对象不会仅通过声明引用类型变量来自动初始化,所以这让我有点困惑。
谢谢!
泄漏内存吗?
是的。myObj
赋值将调用默认的复制赋值运算符,因为您未提供覆盖。因此,将执行逐个成员复制,并用分配源中的myPtr
实例覆盖分配目标的myPtr
实例。在违反三/五/零规则的一个或多个部分时,经常会遇到两个问题:
- 您将丢失作业目标的原始
myPtr
内容。因此,该指针唯一引用的原始内存被泄漏。 - 现在,您可以在两个
myPtr
成员中共享相同的指针值:赋值操作的源和目标。
后者尤其令人不安,因为myObj
在TestObject
构造函数中完成赋值后立即离开范围。这样做,myObj
将被摧毁,随之而来的是,它myPtr
释放。此外,myObj
是通过值而不是引用传递给该构造函数的,因此隐式副本很可能已经发生(由于右值移动语义,省略了副本(。因此,三个MyObj
对象很可能正在吊起一个myPtr
,它们都引用了相同的内存,一旦一个释放它,其余的都在不知不觉中悬挂着悬空的指针。对这些指针的任何取消引用或free
-ing 都将调用未定义的行为。
分配给本地对象是否会调用被替换对象的析构函数?
析构函数仅被调用以保持其同名。 即,仅在对象被销毁时调用它们(尽管手动调用析构函数以进行放置 - 新语义(。除非引入临时,否则复制赋值不会这样做,而代码中的情况并非如此。
如果对象实例变量直接在构造函数中赋值,编译器是否会优化对象实例变量的赋值?
否,但成员初始化列表可以在这方面提供帮助。
现代C++编程技术经常使用RAII以多种方式完成您似乎正在尝试的事情,具体取决于您真正想要实现的目标。
每个实例的唯一数据
如果目标是每个实例的唯一动态数据,则可以根据基本需求,使用std::vector<char>
或简单地std::string
轻松完成此操作。两者都是 RAII 数据类型,通常足以满足动态内存管理需求。
class MyObj
{
std::vector<char> myData;
public:
MyObj() : myData(30)
{
}
}
class TestObject
{
MyObj _myObj;
public:
TestObject(MyObj myObj)
: _myObj(std::move(myObj))
{
}
};
这消除了MyObj
中析构函数的需要,并在TestObject
构造函数中使用了移动语义以及前面提到的成员初始化列表。MyObj
的所有实例都将提升一个独特的char
向量。MyObj
和TestObject
的所有分配操作都使用默认实现。
作业共享内存
你不太可能想要这个,但它同样可行:
class MyObj
{
std::shared_ptr<char> myPtr;
public:
MyObj() : myPtr(new char[30])
{
}
};
class TestObject
{
MyObj _myObj;
public:
TestObject(MyObj myObj)
: _myObj(std::move(myObj))
{
}
};
代码相似,但成员类型不同。现在myPtr
是指向char
数组的共享指针。对其他myPtr
的任何分配都将加入共享列表。简而言之,赋值意味着两个对象引用相同的数据,引用计数确保最后一个人站立扫除混乱。
注意:使用这样的共享指针可能会发生内存泄漏,因为new
可能会成功,但共享指针的共享数据块可能会引发异常。这在第 17 C++中得到解决, 其中std::make_shared
支持阵列分配
这些只是完成您可能尝试完成的任务的几种方法。我鼓励您在提供的链接和本网站上阅读有关三/五/零规则和 RAII 概念的信息。有很多例子可能会回答您可能遇到的更多问题。
- C++功能泄漏内存,我是C++新手,不确定如何解决
- 我的堆栈弹出式磁带的实现是否泄漏内存?
- 将 c++ 向量转换为字符 ** 而不会泄漏内存
- 析构函数 C++ 使泄漏内存
- 构造函数对象赋值是否泄漏内存
- corba :: orb_init泄漏内存
- Gmock泄漏内存
- 如何在不泄漏内存的情况下删除链接列表
- Visual C ODBC关闭记录集泄漏内存
- 为什么泄漏内存比在动态数组上执行 delete[] 慢
- OpenGL正在泄漏内存.哪个对象未释放
- 可以std ::退出泄漏内存
- uiautomation findall泄漏内存
- 为什么在此OpenCL代码中泄漏内存,为什么要泄漏内存
- pthread在完成后会泄漏内存
- win32 标准::线程泄漏内存
- 返回指向同一变量的指针是否会泄漏内存
- 使用clectType(new any_type())可能会泄漏内存泄漏
- Windows开发:如何确定我的应用程序是否正在泄漏内存
- WinHttp打开泄漏内存