std :: vector size未设置且数据未正确分配 - >下标范围错误[关闭]

问题描述 投票:-2回答:1

调试断言失败!

程序:文件:c:\ program files(x86)\ microsoft visual studio \ 2017 \ community \ vc \ tools \ msvc \ 14.15.26726 \ include \ vector Line:1742

表达式:矢量下标超出范围

有关程序如何导致断言失败的信息,请参阅有关断言的Visual C ++文档。

(按重试调试应用程序)Sandbox.exe已触发断点。

My Visual Studio environment

我正在尝试为另一个项目编写一个Variable维(如1种类型,包含任何n×m矩阵)矩阵库,所以我想创建和修改“2D”数字数组。为此,我使用了std::vectorstd::vector

我理解错误是说我试图访问的索引超出范围。即试图访问3x1阵列的值[5] [8]。查看调试信息,Multiply函数标记错误,问题本身可能是“2D向量”dataout.data的赋值,这可能意味着它是构造函数的错,对吧? (但矩阵是否正确创建,最初......?)

这是我的代码(忽略缺少干净的namesapces / typedef - 当我重构时我会理清所有这些,我喜欢这样离开它所以我知道在哪里/什么都是)

//maths.还

#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;

由于函数/方法等被调用,我认为所有代码都是相关的 - 我删除了其他所有代码(函数的重载,添加,减法等)

c++ matrix size stdvector subscript
1个回答
1
投票

这条线

std::vector<std::vector<float>> data(rows, std::vector<float>(cols, 0.0f));

创建一个名为data的新局部变量,该变量与您的属性Matrix :: data同名

这称为阴影并且非常糟糕,因为您对此本地操作所做的任何操作都不会触及该属性。

一个体面的编译器会发出警告,告诉你这件事。

你能建议最好的解决方案吗?是否只是删除该行?

是。

如果您使用std :: vector :: push_back()而不是赋值,那么您不需要调整大小。对于非常大的数据集,这会慢一点。

© www.soinside.com 2019 - 2024. All rights reserved.