标准库字符串的新位置内存泄漏

Posted

技术标签:

【中文标题】标准库字符串的新位置内存泄漏【英文标题】:Memory leak in placement new of standard library string 【发布时间】:2012-04-27 07:23:41 【问题描述】:

我在放置新的标准库字符串时面临内存泄漏。

下面我给出了显示泄漏的代码。

string string1("new string");
char _string[sizeof(string)];
new(_string) string(string1);

使用dbx发现泄漏,如下图所示

Actual leaks report    (actual leaks:            1  total size:         52 bytes)

  Total     Num of  Leaked     Allocation call stack
  Size      Blocks  Block
                    Address
==========  ====== =========== =======================================
        52       1    0x43f68  operator new < std::basic_string<char,std::char_traits<char>,std::allocator<char> >::__getRep < std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string < main


Possible leaks report  (possible leaks:          0  total size:          0 bytes)

这是真正的内存泄漏还是 dbx 将其解释为泄漏?

【问题讨论】:

您是否在任何地方为_string 调用std::string 析构函数? 你想达到什么目的?也就是说,你为什么使用新的展示位置?您尝试使用这个损坏的解决方案解决的原始问题是什么(我的意思是,placement new 是损坏的解决方案,除非您的代码在没有真正内存管理的环境中执行)? 请注意,您的_string 数组不能保证与std::string 正确对齐。 【参考方案1】:

你仍然需要为你通过placement new创建的字符串对象调用析构函数。

std::string 为其存储在堆上的字符分配存储空间(除非您指定自定义分配器,这可能是您在此处所追求的),并且您正在泄漏它。 (sizeof(string) 是一个常量,不依赖于存储在字符串中的内容。)

【讨论】:

Nitpick:您需要显式调用由放置new创建的所有对象的析构函数。示例:name.~string();. 您好,非常感谢您的回答。我之前曾尝试将析构函数称为 _string->~string() ,它给出了编译错误并被击中,我很困惑在这种情况下是否应该调用 STL::destructors。现在我只是尝试将类型转换为字符串并调用析构函数。现在它没有泄漏。 ((string*)_string)->~string() @user1357856:这是正确的做法,但更正确的做法是不要在案例中使用placement new,它不会买你任何东西(除了调用析构函数的稍微疯狂的语法)。字符串“contents”仍然在堆上分配有new,还有你在那里的代码,所以据我所知,它没有做任何有用的事情。

以上是关于标准库字符串的新位置内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

测试驱动开发与内存泄漏

如何在没有内存泄漏的类中存储位置(CLLocationCoordinate2D)?

Sidekiq 工作人员正在泄漏内存

Java 标准 API 中的内存泄漏陷阱

如何消除其他库引起的内存泄漏?

如何检测内存泄漏