创建对象时调试断言失败
Debug Assertion Failed while creating Object
我正在尝试为大学构建一个简单的矩阵代数应用程序。尝试从输入文件添加数据时,我使用以下方法:
Matrix createMatrix(string filename, int rowRestriction, int colRestriction)
{
try{
ifstream file;
string line = "";
vector<string> curLine;
int cols = -1, rows = 0;
vector<vector<double>> values;
file.open(filename);
if(!file.is_open())
{
cout << "No file could be loaded, please check whether the input file is placed inside the working directory.n";
throw 1;
}
while(getline(file,line))
{
rows+=1;
curLine = split(line);
if(cols == -1)
{
cols = curLine.size();
cout << "Matrix appears to have " << cols << " Columns.n";
if(colRestriction != NO_RESTRICTION && cols != colRestriction)
{
cout << "The Matrix you provided does not fulfill the column restriction of " << colRestriction << " Columns, please check your input file.n";
throw 2;
}
}
else if(cols != curLine.size())
{
cout << "Invalid Matrix supplied. Varying amount of columns. Please check input file " << filename << ".n";
throw 3;
}
cout << "Saving Row "<<rows<<"n";
values.resize(rows);
values[rows-1].resize(cols);
for(int i = 0; i < curLine.size(); i++)
{
if(isValidNumber(curLine[i]))
try
{
values[rows-1][i] = atof(curLine[i].c_str());
}
catch(int e)
{
cout << "Exception No. " << e << " has occurred. Presumably your input file does not contain valid floating point numbers.n";
throw 4;
}
else
{
cout << "Your file contains invalid characters, please check your input file "" << filename << "".n";
throw 5;
}
}
}
if(rowRestriction != NO_RESTRICTION && rowRestriction != rows)
{
cout << "The Matrix you provided does not fulfill the row restriction of " << rowRestriction << " Rows, please check your input file.n";
throw 6;
}
cout << "Matrix Data has been read successfully, your matrix has " << rows << " Rows and " << cols << " Columns. It is " << ((rows==cols)?"":"not ") << "quadratic.n";
Matrix m = Matrix(rows, cols, values);
m.setValidity(true);
return m;
}
catch(int e)
{
cout << "Exception No. " << e << "occurred.n";
}
}
以下是"矩阵"的构造函数:
Matrix::Matrix(int rows, int cols, vector<vector<double>> data)
{
this->rows = rows;
this->cols = cols;
this->data = data;
}
这是头文件:
#pragma once
#include <vector>
using std::vector;
class Matrix
{
public:
Matrix(int rows, int cols, vector<vector<double>> data);
~Matrix(void);
int getCols();
int getRows();
private:
int rows, cols;
vector<vector<double>> data;
};
我收到以下错误消息 - 它仅在添加行Matrix m = Matrix(rows, cols, values);
时出现(见上文)。
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: ...al studio 2012ProjectsMatrixalgebraDebugMatrixalgebra.exe
File: f:ddvctoolscrt_bldself_x86crtsrcdbgheap.c
Line: 1322
Expression: _CrtIsValidHeapPointer(pUserData)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
我只知道这是一些菜鸟的错误,但我已经尝试了很长一段时间,但没有成功。算法本身一直工作得很好,直到最后几行。
编辑:更改了OP以反映新问题
EDIT2:由于我的解构函数而引发此新错误,请参见下文
Matrix::~Matrix(void)
{
delete &data;
}
为什么会这样 - 我真的很感激对此的解释,或者关于这个问题的一些学习材料。
问题就在这里:
Matrix *createMatrix(string filename, int rowRestriction, int colRestriction) {
// ...
Matrix m = Matrix(rows, cols, values);
return &m;
}
您将返回一个指针,指向在函数内的堆栈上创建的变量。当函数返回时,该指针将无效,使用它将导致未定义的行为。幸运的是,调试运行时通过抛出断言来告诉您这一点。
(编辑)发出错误情况信号的可能解决方案:
A. 动态为矩阵分配存储
Matrix *createMatrix(string filename, int rowRestriction, int colRestriction) {
// ...
Matrix *m = new Matrix(rows, cols, values);
return &m;
}
优点:做你想做的事,不需要更改代码
缺点:在堆上创建一个矩阵,谁来释放它?
B. 修改函数
bool loadMatrixFromFile(string filename, int rowRestriction, int colRestriction, Matrix& m) {
// ...
// If something goes wrong -> return false
Matrix newMatrix(rows, cols, values);
m = newMatrix;
return true;
}
// Call like this:
Matrix m;
bool retVal = loadMatrixFromFile("",bla , bla, m);
优点:我认为这是一种可以推荐的方法,避免了无法使用 RVO 时复制矩阵的开销,允许您发出错误条件的信号。另外:函数名称现在还描述了它的实际作用:-)
缺点:我能想到的都没有。
您的问题是您在"createMatrix"函数中返回局部变量的地址。
为什么 createMatrix 返回一个 Matrix*? 在那之前,你避免了指针。 你的createMatrix应该返回一个Matrix对象,而不是一个指针。
Matrix createMatrix(string filename, int rowRestriction, int colRestriction)
{
//....
Matrix m = //;
return m;
}
这就是我所期望的,或者类似的东西。
绝对是一个反模式:从驻留在自动内存中的ab对象返回一个指针(或引用),即在堆栈上。返回后发生的下一件事是,它会破坏变量内容 - 任何东西。
Matrix * x(...){
...
Matrix m = ...;
return &m;
}
在您的情况下,您可以使用 new 并返回指向堆上一段动态内存的指针:
Matrix * m = new Matrix( nrow,... );
return m;
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- uint_not_usable_without_attribute在业力规则中使用数字生成器时静态断言失败
- 从 exe 文件 (Visual Studio ) 启动时调试断言失败
- 断言"id < 0"在Qt ActiveX中失败
- 在 CppUnit 中测试中止断言失败
- 使用扫描的调试断言失败
- MS 本机单元测试 - 断言::线程失败不起作用
- 为什么我的Qt程序在断言失败后继续运行?
- 图片不显示,关闭时出错 --> 调试断言失败!表达式:is_block_type_valid(标头>_block_use)
- 访问提升:shared_ptr 主范围外崩溃,断言失败:px != 0.指针的正确用法是什么?
- C++ 调试断言失败 - 矢量下标超出视觉工作室的范围
- 错误:断言失败 (src.type() == CV_8UC1) 在阈值中
- Boost Beast 异步服务器失败,断言失败:(id_ != T::id) 在多个 aync 调用中
- 使用imwrite OpenCV时断言失败
- 调试断言失败的缓冲区!=nullptr
- 使用 ofstream 写入文本文件时断言失败
- OpenCV 错误:相机校准:断言在matrix_wrap.cpp失败
- 提升继续恢复断言失败
- 获取有关调试断言失败的错误:表达式:"(_Ptr_user &(_BIG_ALLOCATION_ALIGNMENT -1)) == 0" &&0
- 打破gdb中失败断言的正确方法是什么