C/C++字符串内存泄漏?

balp4ylt  于 2023-02-07  发布在  C/C++
关注(0)|答案(2)|浏览(2813)

我在我的一个应用程序中使用STL string,最近我测试了它的内存泄漏,我注意到我的许多字符串在程序结束时没有被正确地释放。
我用其中一个字符串测试了以下代码(不是逐字的):

const string* cppString = &obj->objString;
const char* cString = cppString->c_str();
delete obj;

之后,我设置了一个断点,并注意到,虽然cppString指向的string不再存在,但cString仍然指向一个C样式字符串,这无疑是最后未能释放的字符串。
在C/C++字符串如何工作方面我是否遗漏了一些东西?我如何让字符串的C表示也被释放?
我的obj类是Dialog类型,它继承了Popup,我想可能是这样,因为当我删除obj时,我把它当作Popup*,但是我在一个小的单独的程序中尝试过,作为父类删除正确地删除了子成员变量(当然,这是有意义的)。
我在Visual Studio中使用了内存泄漏跟踪,它显示最终泄漏的字符串是在我创建Dialog并将objString设置为作为对构造函数的引用传递的字符串时创建的字符串。

iecba09b

iecba09b1#

你所看到的是未定义的行为--这实际上并不是内存泄漏。C字符串的内存已经被释放了(至少在你看来是这样),但是那里的数据在技术上仍然是可以访问的。当你释放内存的时候,内存通常不会被擦除,所以那里的数据通常会一直存在,只要内存没有被后续的分配所重用。
在数据被解除分配后阅读数据是未定义的行为:您可能会得到释放之前的数据,可能会得到垃圾数据,可能会使程序崩溃,甚至可能会擦除硬盘驱动器(尽管这种可能性不大)。
只要std::string对象被正确地释放,那么用于其C字符串表示的任何内存也将被释放,您不需要担心这个问题。

EDIT:事实上你的对象没有被完全销毁,因为父类Popup没有虚析构函数,结果是子类Dialog的析构函数没有被调用,所以std::string示例的析构函数没有被调用。

fbcarpbf

fbcarpbf2#

问题很可能不在std::string中,而在obj中(无论是什么类型)。注意,您删除了obj,而不是cppString。我猜测obj没有将objString存储在智能指针类中,也没有在其析构函数中删除objString,因此您有泄漏。

相关问题