Memory leak how to find and delocate

时间:2018-09-22 23:05:11

标签: c++ memory-management memory-leaks

I am running a memory leak counter on my project and it says 2 of my 4 allocations are leaking. I think i have found them but am not sure, and dont even know how to delocate them. Two are members, m_color and m_data and two are parameters to those members, one in m_color and one in m_data.

class Screen {
public:
    Screen(uint16_t width, uint16_t height)
        : m_width(width), m_height(height),
          m_size(width*height), m_color(new TerminalColor[m_size]), <-?
          m_data(new char[m_size]) <-?
    {}
    ~Screen(){}
    void clear();
    void fill(char ch, const TerminalColor &color);
    void fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char ch, const TerminalColor &color);
    void set(uint16_t x, uint16_t y, char ch, const TerminalColor &color);
    void setText(uint16_t x, uint16_t y, const std::string& text,  const TerminalColor &color);
    void setTextRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const std::string& text,  const TerminalColor &color);
    void draw(Terminal &terminal);
private:
    const uint16_t m_width;
    const uint16_t m_height;
    const uint32_t m_size;
    TerminalColor *m_color; <-?
    char *m_data; <-?
};

Is it the members who are leaking, since i can not delocate them after i put in parameters? How to delocate them if so?

1 个答案:

答案 0 :(得分:2)

泄漏的原因是|的构造函数正在使用两个Screen表达式动态分配内存,并且没有相应的new表达式。

由于这个原因,像这样的简单函数

delete

将导致泄漏,因为 void f() { Screen x(some_width, some_height); // x is destructed as f() returns } 的构造函数分配的内存将永远不会释放。

一种解决方案是在析构函数中添加相应的Screen表达式,例如(在类定义内)

delete

请注意,该类可能还有其他构造函数-某些构造函数是由编译器自动生成的,除非您防止这样做(您没有这样做)。必须确保所有构造函数都以类似的方式分配内存,以避免未定义的行为。例如,默认生成的副本构造函数将复制指针,而不是进行动态内存分配。因此,使用它会导致 ~Screen() { delete [] m_color; delete [] m_data; }; 的两个实例包含指向同一动态分配的内存的指针。当这些对象随后都被销毁时,共享内存将被释放两次。然后,该行为是不确定的。

一个更好的选择是避免使用原始指针,而使用标准容器。例如,将Screen的类型设为m_color,将std::vector<TerminalColor>的类型设为m_data,然后使用类似

的方法在构造函数中对其进行初始化
std::vector<char>

使用标准容器的优点是您不需要在Screen(uint16_t width, uint16_t height) : m_width(width), m_height(height), m_size(width*height), m_color(m_size), // initialise m_color to have m_size elements m_data(m_size) // initialise m_data to have m_size elements {} 的析构函数中执行任何操作,因为该内存将自动释放。它还可以确保其他构造函数正常运行(即避免内存泄漏),除非您尽力改变这些构造函数的行为

我选择使用Screen作为标准容器类型。根据需要,您可能希望使用其他容器类型。

使用std::vector时的权衡取舍是您可能需要对数组元素的访问方式进行较小的调整(例如,如果需要将指针传递到std::vector的第一个元素传递给需要数组的函数,请传递m_color而不是&m_color[0]),但是这些调整很简单。