gpt4 book ai didi

c++ - 从释放的指针 move 会泄漏内存吗?

转载 作者:行者123 更新时间:2023-12-01 22:50:44 42 4
gpt4 key购买 nike

我有以下代码:

std::unique_ptr<T> first = Get();

T* ptr_to_class_member = GetPtr(obj);
*ptr_to_class_member = std::move(*first.release());

在没有拷贝、1 次 move 且没有内存泄漏的情况下,这是否会像预期的那样运行?

最佳答案

*ptr_to_class_member = std::move(*first.release());

只是以first 指向的对象作为参数调用T 的 move 赋值运算符。这可能会正确传输一些数据,但未调用 delete 或对象,因此既不会执行 T::~T 也不会释放对象的内存。

T = std::string 的示例中,这将导致字符串对象的后备存储正确地从 move 赋值的 rhs 转移到 lhs,但动态分配的内存size sizeof(std::string) 仍然会被泄露。

对于某些类,缺少对象的析构函数调用可能会导致额外的麻烦,因为 move 赋值只需要将 rhs 保留在未指定但有效的状态,这可能仍然需要释放额外的资源。

你需要做的

*ptr_to_class_member = std::move(*first);
first.reset();

为了防止内存泄漏。


为了说明这里出了什么问题,以下代码实现了内存(取消)分配和特殊成员函数的打印:

#include <iostream>
#include <memory>
#include <new>
#include <utility>


struct TestObject
{
TestObject()
{
std::cout << "TestObject::TestObject() : " << this << '\n';
}

TestObject(TestObject&& other)
{
std::cout << "TestObject::TestObject(TestObject&&) : " << this << ", " << &other << '\n';
}

TestObject& operator=(TestObject&& other)
{
std::cout << "TestObject::operator=(TestObject&&) : " << this << ", " << &other << '\n';
return *this;
}

~TestObject()
{
std::cout << "TestObject::~TestObject() : " << this << '\n';
}

void* operator new(size_t size)
{
void* const result = ::operator new(size);
std::cout << "memory allocated for TestObject: " << result << '\n';
return result;
}

void operator delete(void* mem)
{
std::cout << "memory of TestObject deallocated: " << mem << '\n';
::operator delete(mem);
}
};


template<class Free>
void Test(Free free, char const* testName)
{
std::cout << testName << " begin -------------------------------------------\n";

{
auto ptr = std::make_unique<TestObject>();
std::cout << "object creation done\n";
free(ptr);
}

std::cout << testName << " end ---------------------------------------------\n";
}

int main()
{
TestObject lhs;

Test([&lhs](std::unique_ptr<TestObject>& ptr)
{
lhs = std::move(*ptr);
ptr.reset();
}, "good");
Test([&lhs](std::unique_ptr<TestObject>& ptr)
{
lhs = std::move(*ptr.release());
}, "bad");

}

可能的输出:

TestObject::TestObject() : 0000009857AFF994
good begin -------------------------------------------
memory allocated for TestObject: 000001C1D5715EF0
TestObject::TestObject() : 000001C1D5715EF0
object creation done
TestObject::operator=(TestObject&&) : 0000009857AFF994, 000001C1D5715EF0
TestObject::~TestObject() : 000001C1D5715EF0
memory of TestObject deallocated: 000001C1D5715EF0
good end ---------------------------------------------
bad begin -------------------------------------------
memory allocated for TestObject: 000001C1D5715EF0
TestObject::TestObject() : 000001C1D5715EF0
object creation done
TestObject::operator=(TestObject&&) : 0000009857AFF994, 000001C1D5715EF0
bad end ---------------------------------------------
TestObject::~TestObject() : 0000009857AFF994

您可以清楚地看到第二种情况中缺少析构函数调用和释放,这是与您询问的代码匹配的情况。

关于c++ - 从释放的指针 move 会泄漏内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74411342/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com