【问题标题】:How to properly deallocate memory?如何正确释放内存?
【发布时间】:2020-06-23 00:42:41
【问题描述】:

类:

class Menuitem
{
private:
    char* text;

    Menuitem();
    Menuitem(const char*);
    ~Menuitem();
    Menuitem(const Menuitem& ) = delete;
    Menuitem& operator=(const Menuitem& ) = delete;
    friend class Menu;
public:
};

class Menu
{
private:
    char* title;
    Menuitem* items;
    int identation = 0;
    int amount = 0;
public:
    Menu();
    Menu(const char*, int = 0);
    ~Menu();
    bool isEmpty() const;
    int run() const;
    void add(const char*);
    void display() const;
    Menu& operator=(const char* nTitle);
    operator int() const;
    Menu& operator=(const Menu& );
    operator bool() const;
    Menu& operator<<(const char* );
};

功能:

Menu& Menu::operator=(const char* nTitle)
{
    if (nTitle[0] != '\0' && title[0] != '\0')
    {
        delete[] title;
        title = new char[strlen(nTitle)+1];
        strcpy(title, nTitle);
    }
    else if (title[0] != '\0' && nTitle == 0)
    {
        delete[] title;
        title = nullptr;
    }
    else
    {
        title = nullptr;
    }
    return *this;
}

Menu& Menu::operator=(const Menu& nMenu)
{
    if (nMenu.title[0] != '\0' && title[0] != '\0')
    {
        delete[] title;
        title = new char[strlen(nMenu.title)+1];
        strcpy(title, nMenu.title);
    }
    else if (nMenu.title[0] == '\0' && title[0] != '\0')
    {
        delete[] title;
        title = nullptr;
    }
    else
    {
        title = nullptr;
    }


    if (!amount)
        for (int i = 0; i < amount; i++)
        {
            if (items[i].text[0] != '\0')
            {
                delete[] items[i].text;
                items[i].text = nullptr;
            }
        }
    amount = 0;

    for (int i = 0; i < nMenu.amount; i++)
    {
        if (nMenu.items[i].text != nullptr)
        {
            items[i].text = new char[strlen(nMenu.items[i].text)+1];
            strcpy(items[i].text, nMenu.items[i].text);
        }
        else
        {
            items[i].text = nullptr;
        }
    }
    amount = nMenu.amount;
    identation = nMenu.identation;
    return *this;
}

我的代码有很多功能,但我认为这些(或其中一个)功能会导致错误。代码显示了我需要的内容,但最后当我使用析构函数清除 Menu 中的指针时

Menu::~Menu(){delete[] title;删除[] 项;}

我收到以下错误:

malloc: 已释放对象 0x102832838 的校验和不正确:可能在释放后修改。

也许我正在尝试双重删除某些内容,但找不到内容和位置

【问题讨论】:

  • 使用std::string代替char指针和手动内存管理;所有这些问题都会消失
  • 我不允许使用std::string
  • 在这种情况下,创建你自己的类,就像 std::string 一样(无论如何你都必须做同样的工作,并且在你自己的类中进行测试要容易得多,而不是把它和菜单类代码混在一起)
  • 假设您使用的是 Linux 机器,您是否尝试过使用 valgrind 或使用地址清理来编译您的代码?

标签: c++ memory dynamic-memory-allocation


【解决方案1】:

如何正确释放内存?

通过使用 RAII 容器(例如 std::string)管理分配。


如果您需要进行手动内存管理,请遵循以下规则:

  • 切勿管理任何类中的内存,除非是只负责管理该内存的类。
  • 对于每个新的,始终只有一个删除。切勿多次删除任何内容。
  • 仅将delete 用于new 和delete[] 用于new[]。
  • 切勿删除 new 未返回的任何内容。
  • 始终在每个构造函数中初始化拥有指针。
  • 切勿让拥有指针指向除有效对象或 nullptr 以外的任何对象作为类不变量。
  • 永远不要让拥有的指针与另一个对象具有相同的值作为类不变量。
  • 永远不要分配给拥有的指针,除非你刚刚删除它。
  • 永远不要删除拥有的指针,除非您立即为其分配一个有效值(除了在析构函数中,您只需删除)。
  • 永远不要在除分配它的类之外的任何地方删除指针。
  • 实现所有五个析构函数、复制/移动构造函数/赋值。

也许我正在尝试双重删除某些内容,但找不到内容和位置

首先创建一个mcve。

【讨论】:

  • 我不允许使用std::string
  • @Dr_Cringe 然后改用std::unique_ptr&lt;char[]&gt;。
  • 我也不能用这个。我必须使用 char 指针来做到这一点
  • @Dr_Cringe 然后用char指针实现自己的字符串类,这样就不用为每个需要的类重复内存管理代码了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 1970-01-01
  • 2023-03-11
  • 2020-11-28
  • 2011-06-26
  • 2021-04-21
相关资源
最近更新 更多