2014-01-23 13 views
0

假设T包含一个数组,其大小可能因初始化而异。我指针传递到载体中以避免复制的所有数据,并初始化如下:使用std :: vector控制内存<T*>

for(int i=10; i < 100; i++) 
    std::vector.push_back(new T(i)); 

在退出,一个delete S中的向量的元素的。如果包含在T中的数据也是一个指针,即使有很好的析构函数,是否也有内存丢失的风险?例如

template<class M> class T{ 
    M * Array; 
public: 
    T(int i) : Array(new M[i]){ } 
    ~T(){ delete Array;} 
}; 
+0

从我知道这是坏的风格,把元素创建新的向量。无论如何,向量的内存将在堆上... – guitarflow

+1

为什么不在'T'里面使用一个向量来保存自己处理[Rule of Three](http://stackoverflow.com/questions/4172722)的麻烦?为什么不使用'vector '来保存删除元素时的麻烦? –

+1

所以'T'有一个'M'类型的底层数组,并且你正在'std :: vector'中存储指向'T'的指针?为什么不使用'std :: vector >'并避免所有不必要的手动内存管理? – Chad

回答

3

没有与你的类T两个主要问题:

  • 您使用delete,而不是delete []删除的磁盘阵列,让未定义行为
  • 你没有实现(或删除)的拷贝构造函数和复制赋值运算符(根据Rule of Three),所以存在两个对象都试图删除相同数组的危险。

这两个都可以通过使用std::vector而不是编写自己的版本来解决。

最后,除非你有一个很好的理由(例如多态性)来存储指针,否则使用std::vector<T>,这样就不需要手动删除元素。当移除一个元素或者离开矢量的范围时,很容易忘记这么做,特别是当引发异常时。 (如果您确实需要指针,请考虑unique_ptr自动删除对象)。

2

答案是:不。

要么使用

std::vector<std::vector<M>> v; 
v.emplace_back(std::vector<M>(42)); // vector of 42 elements 

或(呸)

std::vector<std::unique_ptr<M[]>> v; 
// C++11 
std::unique_ptr<M[]> temp = new M[42]; // array of 42 elements 
v.emplace_back(temp); 
// C++14 or with handrolled make_unique 
v.emplace_back(std::make_unique<M[]>(42); 

这对于你们所做的一切以最小的开销(特别是最后一个)。

请注意,使用new参数调用emplace_back不像您想要的那样非常安全,即使生成的元素是智能指针。要做到这一点,您需要使用C++ 14中的std::make_unique。有各种各样的实现,它不需要任何特殊的。它只是从C++ 11中省略,并将被添加到C++ 14中。

+0

由于M数组的构造和其unique_ptr包装器的构造之间发生异常的可能性,是不是非常像异常安全的问题? – JAB

+1

@JAB是的,它发生在这里,当它调整大小,以适应一个新的元素时,引发向量抛出,并留下你分配的内存遭受和死亡孤独死亡。查看评论[这里](http://stackoverflow.com/a/3283795/256138)的讨论和[这里](http://stackoverflow.com/q/19472550/256138)更多的例子,它可以咬您。 – rubenvb

+0

@rubenvb那么,'std :: make_unique(new M [42])'和'std :: unique_ptr (new M [42])'有什么区别? 'make_unique'只有当它没有被分配指针时才会更安全,但是本身调用'new'。另外,当只有一个参数时,构造临时'unique_ptr'和使用'make_unique'没有区别,使用后者只会使代码更加一致。 –

相关问题