为什么要使用带有 C 'vector' 的新调用?

新手上路,请多包涵

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

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

原文由 rated2016 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 562
2 个回答

你的第一个说法是不正确的。 vector<someType> myVector 中的元素将一直存在,直到向量被破坏。如果 vector<someType> 是一个局部变量,它会在超出范围时自动销毁。您不需要显式调用 delete 。如果考虑到可能会抛出异常,那么显式调用 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.
}

除此之外,向量确实动态分配内存来存储新元素。两种情况的区别在于:

  • std::vector<int> v v 是堆栈上的一个对象,它动态分配内存以存储元素。

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

原文由 opetroch 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

取决于您所说的“双重分配”是什么意思。

您正在使用动态内存分配为 std::vector 分配内存。 --- 的构造函数对 std::vector std::vector 元素做同样的事情。如果这就是您所说的“双重分配”,那么答案是“是”。

每个人都提到将向量与新调用混合是邪恶的,但为什么呢?

用于

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

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

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

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

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

这些并不完全是 邪恶 的,但是您在应用程序代码中添加了不必要的工作。

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

如果您的应用程序出于对您有意义的原因在某些核心组件中管理低级别数据,则可以使用动态分配的 std::vector 。我认为在你的代码库中散布这样的代码是不可接受的。这是我的看法,很明显。 YMMV。

原文由 R Sahu 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题