关于c ++:析构函数不会删除分配的内存

Destructor not deleting allocated memory

我有一个包含std :: uint_8指针的类,应调用析构函数以删除分配的内存。 我遇到的问题是发生编译器错误,并指出未分配内存,但是我知道我已在默认构造函数中分配了它。
这是我的默认构造函数:

1
2
3
4
5
6
7
8
BigInteger::BigInteger() {
  unsigned char aArray [4];
  aArray[0] = 0;
  m_number = new unsigned char[4]
  m_number = aArray;
  m_digitCount = 0;
  m_sizeReserved = 4;
}

这是我的析构函数:

1
2
3
BigInteger::~BigInteger() {
    delete [] m_number;
}


unsigned char aArray [4]在这里,您在堆栈上创建了一个由4个元素组成的数组。一旦构造函数完成,这些将超出范围。

m_number = new unsigned char[4]现在您在堆上创建4个元素。您分配内存,然后负责清理它。没问题,您可以在析构函数中执行此操作。

m_number = aArray;现在您可以更改m_number指向的内容,从而有效地失去指向分配的内存的指针。现在你漏了。

现在,在此构造函数之外使用m_number都是未定义的行为,因为您正在访问不再拥有的内存。

delete [] m_number;现在您要删除不拥有的内存。 UB。

不要重新分配m_number,您将不会遇到这些问题。更好的是,使用std::vector并观察这些手动内存管理问题逐渐消失。


那条线

1
m_number = aArray;

将局部变量的地址分配给m_number

该地址不能与delete [] m_number;一起使用,分配给new unsigned char[4]的内存地址将被覆盖并丢失。


您有内存泄漏的经典情况。本质上,您正在执行以下操作:

  • 分配内存(m_number = new unsigned char[4])
  • 覆盖指向已分配内存(m_number = aArray)的指针
  • 永远不要删除已分配的内存,因为您不再知道它在哪里-您丢失了指向它的指针(已被覆盖)