vec.data() 是获取 vector 底层指针的安全方式,空容器时返回 nullptr;其生命周期依赖 vector 本身,非 const 场景需谨慎处理 const 正确性,且无法隐式转为 std::array。
vector.data() 是最直接的底层指针获取方式
只要
非空,
就返回指向其首元素的
指针,等价于
,但更安全(空容器时返回
,而
是未定义行为)。
常见错误:用
代替
处理可能为空的 vector,导致崩溃。
在 C++11 起可用,无需额外头文件
返回指针生命周期完全依赖
对象本身——只要
不被移动、析构或重新分配(如
触发扩容),指针就有效
若需长期持有该地址,必须确保
的内存不被重排,或改用
/ 手动
分配
转成 C 风格数组需注意“只是指针,不是复制”
调用
得到的是原数据的视图,不是新数组。想获得独立副本,必须显式拷贝:
常见误判:以为
“转换”出了新数组,结果在
销毁后继续访问该指针,触发野指针读取。
立即学习
“
C++免费学习笔记(深入)
”;
C函数速查手册(CHM版)
C函数速查手册(CHM版)
下载
若目标 API 接收
且只读,
+
通常足够,无需拷贝
若 API 会修改内存且你不希望影响原
,必须分配新内存并拷贝
C++20 起可考虑
替代裸指针,更安全且语义清晰
用 std::array 代替 vector 前提是大小编译期已知
如果 vector 元素个数固定且已知(比如读配置得到 3 个坐标),别硬转——直接用
更合适:
试图把运行时大小的
“转成”
是不可能的,因为
大小必须是常量表达式。
没有
以外的额外开销,
就是元素总大小
不能用
接收
的内容,除非你写循环或结构化绑定逐个赋值
某些嵌入式或性能敏感场景,强制用
可避免堆分配,但代价是失去动态性
vector 转 C 数组时最容易忽略的 const 正确性
函数参数若声明为
,传
没问题;但如果函数签名是
,而你传的是
,就埋下隐患——哪怕 vector 本身是 const,强制去 const 后修改会导致未定义行为。
优先让接收方接受
,而不是在调用侧加
若必须传非 const 指针且原 vector 是 const,只能拷贝一份可修改的副本
检查目标函数是否真需要修改数据——很多旧 C API 声明
实际只读,此时应确认文档或源码,而非盲目去 const
C++ 中 vector 到数组的“转换”,本质是取地址或拷贝数据,没有
隐式转换
机制;真正容易出错的不是语法,而是对内存所有权和生命周期的误判。
vectorvec.data()T*&vec[0]nullptr&vec[0]&vec[0]vec.data()vec.data()vectorvecpush_backvectorstd::arraynewvec.data()std::vector v = {1, 2, 3};
int* arr = new int[v.size()];
std::copy(v.begin(), v.end(), arr); // 或 memcpy(arr, v.data(), v.size() * sizeof(int));
// ... 使用 arr ...
delete[] arr; vec.data()vectorconst T*v.data()v.size()vectorstd::span(v) std::arraystd::array a = {1.0f, 2.0f, 3.0f};
// 底层就是连续栈内存,a.data() 返回的就是标准 C 数组指针 vectorstd::arraystd::arraystd::arraydata()sizeofstd::arrayvectorstd::arrayconst T*vec.data()T*const_cast(vec.data()) const T*const_castT*