可能的动态分配问题
Possible dynamic allocation issues
现在我正在努力使我的代码(简单的 POD 容器)运行 尽可能稳定。我主要关心的是内存分配和释放(new[] 和 delete[] 运算符)。是否有可能从它们中获取任何不良行为(如 SIGSEGV 或异常)?
这是我写的一个小测试示例:
class my_vector{
private:
long* _data;
size_t _size;
size_t _capacity;
public:
my_vector()
{
this->_data = new long[10];
this->_size = 0;
this->_capacity = 10;
};
~my_vector()
{
delete[] this->_data;
};
void add(long value)
{
if (this->_size == this->_capacity)
this->expand();
this->_data[this->_size] = value;
this->_size++;
};
private:
void expand()
{
long* tmp = new long[this->_capacity*2];
memcpy(tmp, this->_data, sizeof(long)*this->_size);
this->_capacity *= 2;
delete[] this->_data;
this->_data = tmp;
};
}
默认情况下,new[]
表达式在失败时抛出异常(例如,如果动态内存分配失败)。
如果正在构造的任何对象的构造函数因抛出异常而失败,则 new []
表达式将具有抛出该异常的(净)效果。在最终发出异常之前还会发生一些其他事情 - 例如,如果动态分配数组中的第三个对象的构造失败,则会调用两个先前构造的对象的析构函数。就调用代码而言,如果发出异常,则 new[]
表达式创建的对象中的 none 曾经存在过。这在标准中有规定。
如果抛出异常但从未捕获到,程序将终止。这是正常的和意料之中的。
A delete []
表达式通常不会抛出异常,除非被销毁对象的析构函数抛出异常。定义抛出的析构函数通常被认为是非常糟糕的做法,因此应该避免。
有一种 nothrow
形式的 new
表达式,它本身不会抛出异常。在这种情况下,new
表达式在失败时给出空指针。
new[]
和 delete []
表达式本身不会导致 SIGSEGV
或任何其他形式的异常终止。如果发生这种情况,则表明某些 other 代码表现出未定义的行为(例如,写到数组末尾之后)。可以在数组中对象的构造函数或析构函数中,也可以在其他代码中。
现在我正在努力使我的代码(简单的 POD 容器)运行 尽可能稳定。我主要关心的是内存分配和释放(new[] 和 delete[] 运算符)。是否有可能从它们中获取任何不良行为(如 SIGSEGV 或异常)? 这是我写的一个小测试示例:
class my_vector{
private:
long* _data;
size_t _size;
size_t _capacity;
public:
my_vector()
{
this->_data = new long[10];
this->_size = 0;
this->_capacity = 10;
};
~my_vector()
{
delete[] this->_data;
};
void add(long value)
{
if (this->_size == this->_capacity)
this->expand();
this->_data[this->_size] = value;
this->_size++;
};
private:
void expand()
{
long* tmp = new long[this->_capacity*2];
memcpy(tmp, this->_data, sizeof(long)*this->_size);
this->_capacity *= 2;
delete[] this->_data;
this->_data = tmp;
};
}
默认情况下,new[]
表达式在失败时抛出异常(例如,如果动态内存分配失败)。
如果正在构造的任何对象的构造函数因抛出异常而失败,则 new []
表达式将具有抛出该异常的(净)效果。在最终发出异常之前还会发生一些其他事情 - 例如,如果动态分配数组中的第三个对象的构造失败,则会调用两个先前构造的对象的析构函数。就调用代码而言,如果发出异常,则 new[]
表达式创建的对象中的 none 曾经存在过。这在标准中有规定。
如果抛出异常但从未捕获到,程序将终止。这是正常的和意料之中的。
A delete []
表达式通常不会抛出异常,除非被销毁对象的析构函数抛出异常。定义抛出的析构函数通常被认为是非常糟糕的做法,因此应该避免。
有一种 nothrow
形式的 new
表达式,它本身不会抛出异常。在这种情况下,new
表达式在失败时给出空指针。
new[]
和 delete []
表达式本身不会导致 SIGSEGV
或任何其他形式的异常终止。如果发生这种情况,则表明某些 other 代码表现出未定义的行为(例如,写到数组末尾之后)。可以在数组中对象的构造函数或析构函数中,也可以在其他代码中。