我刚刚开始我的容器类,我已经遇到了问题:
class Container
{
private:
string* BasePointer; // The starting pointer.
unsigned int Capacity; // The number of values the container can hold.
public:
Container() // Default constructor.
{
Capacity = 1;
BasePointer = new string[Capacity];
}
~Container() // Destructor.
{
delete BasePointer; // Delete the container to prevent memory leaking.
}
};
我收到错误Container Classes(26467) malloc: *** error for object 0x100100088: pointer being freed was not allocated
。我做错了什么?
答案 0 :(得分:7)
XXX ptr = new XXX[size]
应与数组版本delete [] ptr
匹配,而不仅仅是常规delete
。
在C ++中阅读free store management,正如詹姆斯提醒我们的那样 - 在这种情况下请关注rule of three。
答案 1 :(得分:4)
你必须使用删除[]
delete[] BasePointer;
答案 2 :(得分:2)
其他人提到您new[]
与delete
不匹配,您必须将delete
更改为delete[]
才能解决问题。但是,这只是您的第一个问题。
您还需要实现(或至少声明为私有)复制构造函数和复制赋值运算符。否则,请考虑执行此操作时会发生什么:
{
Container c1;
Container c2(c1);
} // c2.~Container(); // frees the memory pointed to by 'BasePointer'
// c1.~Container(); // also frees the memory pointed to by 'BasePointer'.
由于BasePointer
和c1
的{{1}}成员都指向同一个数组,因此会释放两次。
有一些更易于使用的替代方案:
考虑在可能使用动态分配的数组的任何地方使用c2
。由于您的类被称为std::vector
,我假设您正在尝试实现拥有资源的容器,因此您可能不想使用它。
考虑使用Container
或boost::scoped_ptr
(如果您的编译器支持它)来管理指针的所有权。这两个都抑制了隐式声明的复制构造函数的生成,如果您实际尝试使用它们,则强制您实现自己的复制构造函数。
即使您正在实施std::unique_ptr
,您仍然应该利用更原始的容器来为您完成繁重的工作(或者,至少重新实现这些原始容器,以便将繁重的工作整合成一个小的一套公用事业)。
最后,作为一个风格点,您不需要将Container
用于容器。标准库提供malloc
,可用于为对象分配空间和构造对象。
答案 3 :(得分:1)
如果你创建数组,你必须使用delete [] BasePointer;
答案 4 :(得分:0)
要比其他更明确 - 当您new
- 编辑数组类型时,您需要使用delete[]
删除指针。
这不仅发生在使用new T[size]
时,请考虑以下示例:
typedef int T[42];
int* x = new T;
delete[] x; // needs delete[] though you used new without []
一般来说,如果你的对象“拥有”它通过指针保存的对象,你应该考虑使用智能指针(如boost :: scoped_array)。这样,您不必担心解构,抛出异常时会发生什么,实现赋值操作和复制构造函数......