You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用{{}}初始化std::vector是否引发未定义行为?为何与v{}表现不同?

关于std::vector初始化与越界访问的问题解答

先贴出你提供的测试代码:

#include <iostream>
#include <vector>
int main() {
    std::vector<int> v{{}};

    v[10] = 11; // if initialize with v{}, segmentation fault.

    std::cout << "v[10]:" << v[10] << std::endl; // prints v[10]:11
    
    for (auto e : v) // prints only v[x]:0
        std::cout << "v[x]:" << e << std::endl;    
}

// result:
// v[10]:11
// v[x]:0

问题1:通过v[10]访问元素是否会导致未定义行为?

是的,这绝对属于未定义行为。

C++标准明确规定,std::vector的operator[]仅允许访问索引在[0, v.size())范围内的元素。你的代码里,不管是v{{}}还是v{}初始化的vector,v.size()分别是1和0,10都远远超出了合法索引范围。

你看到的"正常运行"只是巧合——v{{}}初始化的vector底层预分配的内存空间(即capacity())刚好足够覆盖索引10的位置,所以写操作没触发内存错误。但这种行为完全不被标准保证,换编译器、换运行环境甚至换个编译选项,都可能直接崩溃或出现更诡异的问题,绝对不能依赖。

问题2:为何使用v{{}}初始化的代码可正常运行,而使用v{}初始化的代码会触发段错误?

核心是两种初始化方式得到的vector状态完全不同:

  • v{}:调用vector的默认构造函数,创建一个空vector,此时v.size() = 0,多数编译器实现下v.capacity()也为0。这时候访问v[10],本质是访问一块根本没分配给vector的内存,触发段错误是必然的。

  • v{{}}:这是列表初始化,外层大括号触发vector的列表构造函数,内层{}会值初始化一个int(结果为0),最终得到的vectorv.size() = 1。而很多编译器(比如GCC、Clang)的vector实现会默认预分配16个元素的空间(即capacity() = 16),这时候虽然v.size()只有1,但预分配的内存能覆盖到索引10的位置,所以写操作没触发段错误。但这依然是未定义行为,只是刚好没撞上内存保护机制而已。

内容的提问来源于stack exchange,提问作者starriet 차주녕

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:45:20