是否保证std :: vector默认构造不会调用new?

时间:2018-02-12 10:39:13

标签: c++ memory-management stdvector

根据the reference,一个简单的std::vector<T> vec;创建了一个emtpy容器(默认构造函数)。这是否保证没有动态内存分配? 或者实现可能选择保留一些内存?

我知道,对于这个空构造函数,自C ++ 11以来,没有类型T的构造。 但是,我想知道,如果还保证堆上没有分配任何内容。即上面的行只是堆栈/成员上的几个nullptr

我用vc140测试了它,它确实没有动态分配。

3 个答案:

答案 0 :(得分:26)

  

这是否保证没有动态内存分配?

没有。然而,非常典型的是,实现不分配存储器。我还没有看到标准的库实现。

  

或者某个实现可能选择保留一些内存?

可能,但那是非典型的。

  

我知道,对于这个空构造函数,自C ++ 11以来没有类型T的构造

也是在C ++ 11之前。

答案 1 :(得分:21)

std库是C ++语言的一部分。

几乎对任何std库类或函数的任何调用都可以做出病态和疯狂的事情。但int x=7;的情况也是如此 - 该标准并非用于防范包含std库的坦率的恶意C ++实现。

话虽如此,std向量的零参数构造函数是noexcept。这意味着意图不分配。无论分配是否成功,恶意实现都可以自由分配,捕获任何错误并继续执行。一个敌对的实现也可以自由计算到47万亿,对随机数据运行一些FFT,启动神经网络并训练它对抗莎士比亚,编写一些十四行诗,然后继续进行,好像什么也没发生。对于C ++中任何操作的不可观察的诗歌构成,该标准无话可说;只要动作没有可观察的(在抽象机器内)副作用,标准就没有意见。

在实践中,std::vector<T>()没有理由分配,并且以后的任何操作都不能假定它已分配。我可以看到一个检测构建分配一些生命周期跟踪令牌来强制执行迭代器失效错误,但这只会在带有额外标志的调试中启用(例如-DCMP_JUN17)。

更多地关注诗歌而不是呼唤新诗。

答案 2 :(得分:1)

没有保证。

如果_ITERATOR_DEBUG_LEVEL> 0,我刚刚遇到的一个反例(就是导致我看到这篇文章)是MSVC2017的STL实现。