new int [size] vs std :: vector

时间:2012-03-16 12:00:44

标签: c++ memory dynamic vector

为了分配动态内存,我一直在C ++中使用向量。 但是最近,在阅读一些源代码时,我发现使用“new int [size]”并在一些研究中发现它也分配了动态内存。

有谁可以给​​我建议哪个更好?我从算法和ICPC的角度来看?

6 个答案:

答案 0 :(得分:13)

在任何情况下,std::vector都是首选。它有一个析构函数来释放内存,而手动管理的内存必须在完成后立即删除。引入内存泄漏非常容易,例如,如果某些内容在删除之前抛出异常。例如:

void leaky() {
    int * stuff = new int[10000000];
    do_something_with(stuff);
    delete [] stuff; // ONLY happens if the function returns
}

void noleak() {
    std::vector<int> stuff(10000000);
    do_something_with(stuff);
} // Destructor called whether the function returns or throws

如果您需要调整大小或复制数组,也会更方便。

首选原始数组的唯一原因是您有极端的性能或内存限制。 vector是一个比指针更大的对象(包含大小和容量信息);它有时会对其对象进行初始化,而原始数组将默认初始化它们(对于普通类型,这意味着它们未被初始化)。

在极少数情况下,这些问题可能很重要,您应该考虑std::unique_ptr<int[]>;它有一个析构函数,可以防止内存泄漏,与原始数组相比没有运行时开销。

答案 1 :(得分:3)

我认为不存在new int[size]更可取的情况。你有时会在预标准代码中看到它,但即便如此,我认为它不是一个好的解决方案;在标准前的日子里,如果你的工具包中没有等效的std::vector,你就写了一个。您可能希望使用new int[size]的唯一原因是在实现预标准向量类。 (我自己的分离和初始化,就像标准库中的容器一样,但对于一个非常简单的矢量类来说,这可能是过度的。)

答案 2 :(得分:3)

即使两个方法都分配动态内存,一个是用于处理任意长度(std::vector<T>)数据的对象,而另一个只是指向大小为{{1}的顺序内存插槽行的指针(在这种情况下为N)。


其他差异

  • 如果您尝试附加新值并且空间不足,int将自动调整分配的数据内存大小。 std::vector<T>不会。

  • 当向量超出范围时,int *将释放已分配的内存,而std::vector<T>则不会。

  • int *几乎没有开销(与向量相比),但int *并不是一个新事物,通常都是非常优化的。你的瓶颈可能在其他地方。

    但是std::vector<T>总是会消耗比std::vector<int>更多的内存,有些操作总会花费更多时间。

    因此,如果存在内存/ CPU限制,并且您希望削减每个周期,您可以使用int *


在某些情况下,一个绝对优于另一个!

  • 当您需要“原始”/“真实”记忆和完全控制时,int *是您最好的选择。

    例如,当您使用placement new

    时 原始/真实内存

    我指的是不通过包装容器管理的东西,例如operator new

  • 当你正在寻找一个容器来处理任意而且不想重新发明有关内存管理的方法; std::vector<T>(或任何其他适当的STL容器)

答案 3 :(得分:1)

在内部,矢量完全相同,它也会关注内存释放。所以没有任何理由使用new运算符。 std :: vector是c ++的一部分,它是标准的,经过测试并且是安全的,当你有一些标准的工作方式时,不要使用原始指针。

答案 4 :(得分:1)

如果需要动态大小的对象序列,请使用向量。如果您需要自己分配原始内存并管理内存,请分配内存。你会发现有时矢量更有用,而在其他时候平坦的内存缓冲更好。

答案 5 :(得分:1)

  

有谁可以给​​我建议哪个更好?

时,矢量更好
  1. 您还没有学过手动内存管理。
  2. 你已经了解它,但还不自信。
  3. 你认为你知道该怎么做,但却在不知不觉中过于自信。
  4. 你真的知道自己在做什么,但可能会犯错误。
  5. 您是一名上师,但以上都不适用,但您的代码可能稍后由同事维护,对于上述任何一位同事都适用。
  6. ...

    1. 几乎总是。
    2. 手动内存管理很容易且通常会导致内存泄漏,更糟糕的是,未定义的行为。