C++ 如何删除使用_strdup()创建的常量字符*

C++ 如何删除使用_strdup()创建的常量字符*,c++,memory,memory-leaks,char,C++,Memory,Memory Leaks,Char,我在VisualStudio中使用以下代码存储构造函数参数char*,并在解构类时将其删除 #include "pch.h" #include <iostream> class A { public: A(const char *fn) { myChar = _strdup(fn); } ~A() { delete[] myChar; } char *myChar; }; int main() {

我在VisualStudio中使用以下代码存储构造函数参数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
}
#包括“pch.h”
#包括
甲级
{
公众:
A(常量字符*fn){
myChar=_strdup(fn);
}
~A(){
删除[]myChar;
}
char*myChar;
};
int main()
{
myA(“拉拉”);
myA.~A();
_CrtDumpMemoryLeaks();//检漏仪
}
如果我不使用delete[]myChar,我将创建内存泄漏。如果我使用它,我会在调试中遇到这个未知错误

正确的方法是什么


delete[]
更改为
free
后:


有许多不同的分配方案。太多了,无法猜测或假设如何释放东西。因此,首先要查找函数的文档。即使只是在谷歌上搜索“msdn\u strdup”之类的东西,也常常能达到或接近目标(对于Windows/Visual Studio/Microsoft附带的东西)

_strdup函数调用malloc为strSource的副本分配存储空间,然后将strSource复制到分配的空间

因为_strdup调用malloc为strSource的副本分配存储空间,所以最好的做法是通过调用_strdup返回的指针上的空闲例程来释放此内存


因此,您需要使用免费的

这里有几个问题

  • 删除[]
    而不是
    免费

    strdup
    来自C库。告诉我们如何清理它

    微软类似的
    \u strdup

    您必须阅读您使用的函数的文档,尤其是在遇到问题时。这就是它存在的原因

  • 您可以手动调用
    A
    的析构函数,但您不应该这样做。

    该对象具有自动存储持续时间,并将自动销毁。当你出于某种原因自己调用析构函数时,这意味着它最终会被调用两次。这意味着错误的释放调用
    delete[]myChar
    也将被调用两次,这显然是错误的

  • 对象的复制语义被破坏。

    好吧,所以你不要复制到这里。但是任何管理内存的对象都应该遵循零规则、三规则或五规则

  • 您检查泄漏的时间太早了。

    调用
    \u crtdumpmomeryleaks()
    时,
    myA
    仍处于活动状态,因此它当然会看到它尚未被销毁/释放,并将其视为内存泄漏。您应该在尝试清除所有资源之后调用该函数,而不是之前

  • 这是您的直接固定代码:

    #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
    }
    
    #包括“pch.h”
    #包括
    甲级
    {
    公众:
    A(常量字符*fn){
    myChar=_strdup(fn);
    }
    A(常数A和其他){
    myChar=_strdup(other.myChar);
    }
    A运算符=(常量A和其他){
    如果(&其他!=此){
    免费(myChar);
    myChar=_strdup(other.myChar);
    }
    归还*这个;
    }
    ~A(){
    免费(myChar);
    }
    char*myChar;
    };
    int main()
    {
    {
    myA(“拉拉”);
    }
    _CrtDumpMemoryLeaks();//检漏仪
    }
    
    这就是它应该是什么:

    #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
    }
    
    #包括
    #include//for std::move
    #包括//for _CrtDumpMemoryLeaks
    甲级
    {
    公众:
    A(std::string str):m_str(std::move(str)){}
    私人:
    std::字符串str;
    };
    int main()
    {
    {
    myA(“拉拉”);
    }
    _CrtDumpMemoryLeaks();//检漏仪
    }
    
    什么?您是否意识到,在您自己手动调用析构函数之后,当
    main()
    退出时,对象将被销毁,并再次调用其析构函数?删除同一个指针两次,您希望完成什么?即使没有任何内存分配或释放,上述代码也会对同一对象调用两次析构函数。这是未定义的行为。C++不这样工作。在正常销毁对象后,为什么不尝试检查内存泄漏?请使用
    std::string
    而不是
    new
    /
    delete
    /
    malloc
    /
    free
    和C字符串库。这将解决您所有的内存问题。(假设您也停止手动调用析构函数,几乎没有理由这样做。)请不要修复与问题代码中的问题相关的错误。它使答案无效。我已还原您上次编辑的内容。我已在您的问题末尾添加了您的新图像。请不要修改代码本身。您可以在末尾添加其他信息。