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

返回语句触发"vector subscript out of range"断言问题求助

问题分析与解决

你遇到的"vector subscript out of range"断言问题,根源出在你的拷贝构造函数里——你误用了reserve()而不是resize(),导致访问未初始化的vector元素时触发越界。

为什么拷贝构造函数会出问题?

std::vector::reserve()只是预留内存空间,不会改变vector的实际大小(size())。你的拷贝构造函数里:

Matrix4(const Matrix4& matrix) {
 _matrix.reserve(4);
 for (unsigned int i = 0; i < 4; ++i) {
 _matrix[i].reserve(4); // 这里的_matrix[i]根本不存在!
 for (unsigned int j = 0; j < 4; ++j)
 _matrix[i][j] = matrix[i][j];
 }
}

当你调用_matrix.reserve(4)后,_matrix的size()仍然是0,循环里访问_matrix[i](i从0到3)直接触发了vector下标越界断言。

至于调试时没进入拷贝构造函数的现象,大概率是编译器开启了返回值优化(RVO),试图直接在调用方的内存空间构造perspective对象,避免拷贝。但一旦优化条件不满足(比如某些调试场景),拷贝构造函数就会被调用,此时断言就触发了——断点显示在return perspective处,是因为拷贝操作是在return语句执行时触发的,调试器的调用栈可能把错误定位到了return行。

修正方案

把拷贝构造函数里的reserve()全部替换成resize(),确保vector的大小正确初始化:

Matrix4(const Matrix4& matrix) {
 _matrix.resize(4); // 先把外层vector的大小设为4
 for (unsigned int i = 0; i < 4; ++i) {
 _matrix[i].resize(4); // 再把每个内层vector的大小设为4
 for (unsigned int j = 0; j < 4; ++j)
 _matrix[i][j] = matrix[i][j];
 }
}

或者更简洁的写法,直接利用vector的拷贝构造:

Matrix4(const Matrix4& matrix) : _matrix(matrix._matrix) {}

这样可以完全避免手动循环,让std::vector自己处理拷贝逻辑,更安全也更高效。

额外验证

你可以在拷贝构造函数里加个断点,或者临时关闭编译器的RVO优化(比如VS里用/Od禁用优化),就能看到拷贝构造函数被调用,此时修正后的代码不会触发断言。

内容的提问来源于stack exchange,提问作者Marin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:19:43