为什么要使用带c ++ vector的新调用?

时间:2018-02-12 23:06:44

标签: c++ vector new-operator

代码vector<someType> myVector;动态分配内存,因此存储的所有元素都将存在,直到调用删除为止。那么下面的vector<someType> *myVector = new vector<someType>();如何与前一个不同(除了作为一个指针)?

这里有双重分配吗? 每个人都提到混合vectornew电话是邪恶的,但为什么呢? 如果它是邪恶的,为什么它是可接受的编译器代码,什么时候可以使用?

3 个答案:

答案 0 :(得分:5)

你的第一个陈述不正确。 ParserError: Error tokenizing data. C error: Expected 5 fields in line 6, saw 7 中的元素将一直存在,直到矢量被销毁。如果vector<someType> myVector是一个局部变量,它将在超出范围时自动销毁。您不需要明确调用删除。如果您考虑到由于可能引发的异常,您的vector<someType>语句可能永远不会到达,导致内存泄漏,那么显式调用delete是容易出错的。 例如。比较以下两种情况

delete

除了上述内容之外,向量动态分配内存以存储新元素也是如此。两种情况之间的区别是:

  • void foo() { std::vector<int> v; v.push_back(1); f(); // f is some operation that might throw exception. } // v is automatically destroyed even if f throws. void bar() { std::vector<int>* v = new std::vector<int>; v->push_back(1); f(); // f is some operation that might throw exception. delete v; // You need to call delete explicitly here. // The vector will be destroyed only if f doesn't throw. } v是堆栈中的一个对象,它动态分配内存以存储元素。

  • std::vector<int> v v是指向动态分配对象的指针,它动态分配内存以存储元素。如前所述,你需要明确地调用delete来销毁这个对象。

答案 1 :(得分:3)

  

这里是否发生了双重分配?

取决于“双重分配”的含义。

您正在使用动态内存分配为std::vector分配内存。 std::vector的构造函数对std::vector的元素执行相同的操作。如果你的意思是“双重分配”,那么答案就是“是”。

  

每个人都提到将矢量与新呼叫混合是邪恶的,但为什么呢?

使用

vector<someType> *myVector = new vector<someType>();

意味着您负责管理myVector的动态分配内存。这引入了一些陷阱:

  1. new vector<someType>()可以抛出std::bad_alloc。您必须添加代码来处理异常。如果不这样做,您将最终终止您的申请。

  2. 您必须确保释放内存。如果不这样做,程序会泄漏内存。

  3. 您必须确保在释放内存后不使用指针。

  4. 这些并不完全是 evil ,但您在应用程序代码中添加的工作量超出了必要的范围。

      

    如果它是邪恶的,为什么编译器的代码可以接受?何时可以使用?

    如果您有一个应用程序,您在某些核心组件中管理低级数据的原因是有意义的,那么使用动态分配的std::vector是可以接受的。我认为将这些代码遍布整个代码库是不可接受的。显然,这是我的看法。 YMMV。

答案 2 :(得分:0)

  

代码vector<someType> myVector;动态分配内存,因此存储的所有元素都将存在,直到调用删除为止

没有。当此对象不再可用时,将删除此内存。

请考虑以下事项:

{
    // Allocate a vector of 4 ints
    vector<int> v(4);

    // Do a lot of operations on this vector

}

此范围结束后,v将被删除(RAII)。所以由它分配的内存会自动释放。

但是

{
    // Allocate a vector of 4 ints
    vector<int> *v = new vector<int>(4);

    // Do a lot of operations on this vector

}

此范围结束后,v对象不会被删除,直到您明确调用delete v

为了比指针更好的方法使对象逃避范围,使用shared_ptrunique_ptrweak_ptr,这样可以避免忘记使用{{1 }}