Mik*_*mik 0 c++ memory memory-leaks char
我在 Visual Studio 中使用以下代码来存储构造函数参数 char* 并在我的类的解构中将其删除。
#include "pch.h"
#include <iostream>
class A
{
public:
A(const char *fn) {
myChar = _strdup(fn);
}
~A() {
delete[] myChar;
}
char *myChar;
};
int main()
{
A myA("lala");
myA.~A();
_CrtDumpMemoryLeaks(); //leak detector
}
Run Code Online (Sandbox Code Playgroud)
如果我不使用 delete[] myChar,则会造成内存泄漏。如果我使用它,我会在调试时遇到这个未知错误。
这样做的正确方法是什么?
更改delete[]为 后free:
这里有几个问题。
你delete[]而不是free.
strdup来自 C 库。文档告诉我们如何清理它。
微软的类似_strdup 工作方式相同。
您必须阅读有关您使用的函数的文档,尤其是在遇到问题时。这就是它存在的原因。
A当您不应该手动调用析构函数时。
对象具有自动存储期限,并会自动销毁。当您出于某种原因自己调用析构函数时,这意味着它最终会被调用两次。这意味着错误的释放调用delete[] myChar也将被调用两次,这显然是陈旧的。
你的对象的复制语义被破坏了。
好的,所以你不要在这里复制它。但是任何管理内存的对象都应该遵循零规则、三规则或五规则。
您过早地检查泄漏。
myA当您调用时仍然活着_CrtDumpMemoryLeaks(),所以当然它会看到它尚未被销毁/释放,并认为这是内存泄漏。您应该在尝试清除所有资源之后调用该函数,而不是之前。
这是您直接固定的代码:
#include "pch.h"
#include <iostream>
class A
{
public:
A(const char *fn) {
myChar = _strdup(fn);
}
A(const A& other) {
myChar = _strdup(other.myChar);
}
A& operator=(const A& other) {
if (&other != this) {
free(myChar);
myChar = _strdup(other.myChar);
}
return *this;
}
~A() {
free(myChar);
}
char *myChar;
};
int main()
{
{
A myA("lala");
}
_CrtDumpMemoryLeaks(); //leak detector
}
Run Code Online (Sandbox Code Playgroud)
它应该是这样的:
#include <string>
#include <utility> // for std::move
#include <crtdbg.h> // for _CrtDumpMemoryLeaks
class A
{
public:
A(std::string str) : m_str(std::move(str)) {}
private:
std::string str;
};
int main()
{
{
A myA("lala");
}
_CrtDumpMemoryLeaks(); // leak detector
}
Run Code Online (Sandbox Code Playgroud)