可能的动态分配问题

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 代码表现出未定义的行为(例如,写到数组末尾之后)。可以在数组中对象的构造函数或析构函数中,也可以在其他代码中。