std::vector 未设置大小且未正确分配数据 -> 下标范围错误
std::vector size not being set and data isn't assigned properly -> subscript range error
Debug Assertion Failed!
Program:
File: c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.15.26726\include\vector
Line: 1742
Expression: vector subscript out of range
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
Sandbox.exe has triggered a breakpoint.
我正在尝试为另一个项目编写可变维度(如 1 种类型以包含任何 n 乘 m 矩阵)矩阵库,因此我想创建和修改“2D”数字数组。为此,我使用了 std::vector
中的 std::vector
。
我知道错误是说我试图访问的索引超出范围。即尝试访问 3x1 数组的值 [5][8]。查看调试信息,Multiply 函数会标记错误,问题本身可能与“2D 向量”data
和 out.data
的分配有关,这可能意味着这是构造函数的错误,对吧? (但是最初创建的矩阵是正确的..?)
这是我的代码(忽略缺少干净的命名空间/类型定义 - 我会在重构时整理所有这些,我喜欢这样保留它所以我知道 where/what 一切都是)
//Maths.h
#pragma once
#include "ckpch.h" // C/C++ standard libraries
#include "Core.h" // API (__declspec(im/export) = CK_API)
namespace Maths {
struct CK_API Matrix {
int Rows, Cols;
std::vector<std::vector<float>> data;
Matrix(int rows, int cols);
Matrix(int rows, int cols, float *values);
~Matrix();
Matrix Multiply(const Matrix& mat) const ;
friend CK_API Matrix operator*(Matrix& left, const Matrix& right);
friend CK_API std::ostream& operator<<(std::ostream& os, const Matrix& mat);
};
}
//Maths.cpp
#include "ckpch.h"
#include "Maths.h"
#include "Log.h" // Loads log info
namespace Maths {
Matrix::Matrix(int rows, int cols) {
Rows = rows;
Cols = cols;
std::vector<std::vector<float>> data(rows, std::vector<float>(cols, 0.0f));
data.resize(rows, std::vector<float>(cols, 0.0f));
}
Matrix::Matrix(int rows, int cols, float* values) {
Rows = rows;
Cols = cols;
std::vector<std::vector<float>> data(rows, std::vector<float>(cols, 0.0f));
data.resize(rows, std::vector<float>(cols, 0.0f));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
data[i][j] = values[j + i * cols];
}
}
}
Matrix::~Matrix() {
this->data.clear();
}
Matrix Matrix::Multiply(const Matrix& mat) const {
int inR1 = this->Rows; // Matrix 1 Rows
int inR2 = mat.Rows; // Matrix 2 Rows
int inC1 = this->Cols; // Matrix 1 Columns
int inC2 = mat.Cols; // Matrix 2 Columns
// (n x m) * (n' x m') --> (n x m')
int outR = this->Rows;
int outC = mat.Cols;
Matrix out = Matrix(outR, outC);
if (this->Cols == mat.Rows) {
for (int i = 0; i < inR1; i++) {
for (int j = 0; j < inC2; j++) {
float sum = 0.0f;
for (int off = 0; off < inR1; off++) {
sum += this->data[off][j] * mat.data[i][off];
}
out.data[i][j] = sum;
}
}
return out;
} else {
CK_WARN("Matrix 1 Column and Matrix 2 Row dimension mismatch! ({0} =/= {1})", Cols, mat.Rows);
}
}
Matrix operator*(Matrix& left, const Matrix& right) { return left.Multiply(right); }
std::ostream& operator<<(std::ostream& os, const Matrix& mat){
os << mat.Rows << " x " << mat.Cols << " - Matrix: " << std::endl;
for (int i = 0; i < mat.Rows; i++) {
for (int j = 0; j < mat.Cols; j++) {
os << mat.data[i][j] << ", ";
}
os << std::endl;
}
return os;
}
}
// SandboxApp.cpp
float val1[2] = {
1.0f, 2.0f
};
Maths::Matrix mat1 = Maths::Matrix(1, 2, val1);
float val2[4] = {
1.0f, 2.0f,
-1.0f, 3.0f
};
Maths::Matrix mat2 = Maths::Matrix(2, 2, val2);
Maths::Matrix mat3 = mat1 + mat2;
Maths::Matrix mat4 = mat1 * mat2;
std::cout << mat1 << std::endl;
std::cout << mat2 << std::endl;
std::cout << mat3 << std::endl;
std::cout << mat4 << std::endl;
由于调用了 functions/methods 等,我认为所有代码都是相关的 - 我删除了所有其他内容(函数重载、加法、减法等)
这一行
std::vector<std::vector<float>> data(rows, std::vector<float>(cols, 0.0f));
创建一个名为 data 的新局部变量,它与您的属性同名 Matrix::data
这称为阴影,非常糟糕,因为您对这个本地所做的任何操作都不会触及该属性。
一个体面的编译器会发出警告告诉你这件事。
Could you suggest the best fix? Would it be just deleting that line?
是的。
如果您使用 std::vector::push_back() 而不是赋值,那么您不需要调整大小。对于非常大的数据集,这会有点慢。
Debug Assertion Failed!
Program: File: c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.15.26726\include\vector Line: 1742
Expression: vector subscript out of range
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application) Sandbox.exe has triggered a breakpoint.
我正在尝试为另一个项目编写可变维度(如 1 种类型以包含任何 n 乘 m 矩阵)矩阵库,因此我想创建和修改“2D”数字数组。为此,我使用了 std::vector
中的 std::vector
。
我知道错误是说我试图访问的索引超出范围。即尝试访问 3x1 数组的值 [5][8]。查看调试信息,Multiply 函数会标记错误,问题本身可能与“2D 向量”data
和 out.data
的分配有关,这可能意味着这是构造函数的错误,对吧? (但是最初创建的矩阵是正确的..?)
这是我的代码(忽略缺少干净的命名空间/类型定义 - 我会在重构时整理所有这些,我喜欢这样保留它所以我知道 where/what 一切都是)
//Maths.h
#pragma once
#include "ckpch.h" // C/C++ standard libraries
#include "Core.h" // API (__declspec(im/export) = CK_API)
namespace Maths {
struct CK_API Matrix {
int Rows, Cols;
std::vector<std::vector<float>> data;
Matrix(int rows, int cols);
Matrix(int rows, int cols, float *values);
~Matrix();
Matrix Multiply(const Matrix& mat) const ;
friend CK_API Matrix operator*(Matrix& left, const Matrix& right);
friend CK_API std::ostream& operator<<(std::ostream& os, const Matrix& mat);
};
}
//Maths.cpp
#include "ckpch.h"
#include "Maths.h"
#include "Log.h" // Loads log info
namespace Maths {
Matrix::Matrix(int rows, int cols) {
Rows = rows;
Cols = cols;
std::vector<std::vector<float>> data(rows, std::vector<float>(cols, 0.0f));
data.resize(rows, std::vector<float>(cols, 0.0f));
}
Matrix::Matrix(int rows, int cols, float* values) {
Rows = rows;
Cols = cols;
std::vector<std::vector<float>> data(rows, std::vector<float>(cols, 0.0f));
data.resize(rows, std::vector<float>(cols, 0.0f));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
data[i][j] = values[j + i * cols];
}
}
}
Matrix::~Matrix() {
this->data.clear();
}
Matrix Matrix::Multiply(const Matrix& mat) const {
int inR1 = this->Rows; // Matrix 1 Rows
int inR2 = mat.Rows; // Matrix 2 Rows
int inC1 = this->Cols; // Matrix 1 Columns
int inC2 = mat.Cols; // Matrix 2 Columns
// (n x m) * (n' x m') --> (n x m')
int outR = this->Rows;
int outC = mat.Cols;
Matrix out = Matrix(outR, outC);
if (this->Cols == mat.Rows) {
for (int i = 0; i < inR1; i++) {
for (int j = 0; j < inC2; j++) {
float sum = 0.0f;
for (int off = 0; off < inR1; off++) {
sum += this->data[off][j] * mat.data[i][off];
}
out.data[i][j] = sum;
}
}
return out;
} else {
CK_WARN("Matrix 1 Column and Matrix 2 Row dimension mismatch! ({0} =/= {1})", Cols, mat.Rows);
}
}
Matrix operator*(Matrix& left, const Matrix& right) { return left.Multiply(right); }
std::ostream& operator<<(std::ostream& os, const Matrix& mat){
os << mat.Rows << " x " << mat.Cols << " - Matrix: " << std::endl;
for (int i = 0; i < mat.Rows; i++) {
for (int j = 0; j < mat.Cols; j++) {
os << mat.data[i][j] << ", ";
}
os << std::endl;
}
return os;
}
}
// SandboxApp.cpp
float val1[2] = {
1.0f, 2.0f
};
Maths::Matrix mat1 = Maths::Matrix(1, 2, val1);
float val2[4] = {
1.0f, 2.0f,
-1.0f, 3.0f
};
Maths::Matrix mat2 = Maths::Matrix(2, 2, val2);
Maths::Matrix mat3 = mat1 + mat2;
Maths::Matrix mat4 = mat1 * mat2;
std::cout << mat1 << std::endl;
std::cout << mat2 << std::endl;
std::cout << mat3 << std::endl;
std::cout << mat4 << std::endl;
由于调用了 functions/methods 等,我认为所有代码都是相关的 - 我删除了所有其他内容(函数重载、加法、减法等)
这一行
std::vector<std::vector<float>> data(rows, std::vector<float>(cols, 0.0f));
创建一个名为 data 的新局部变量,它与您的属性同名 Matrix::data
这称为阴影,非常糟糕,因为您对这个本地所做的任何操作都不会触及该属性。
一个体面的编译器会发出警告告诉你这件事。
Could you suggest the best fix? Would it be just deleting that line?
是的。
如果您使用 std::vector::push_back() 而不是赋值,那么您不需要调整大小。对于非常大的数据集,这会有点慢。