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?
答案 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]
),但是这些调整很简单。