
[英]how to fix terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid
[英]terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid (HELP)
编译器没有遇到任何错误,但是我的程序一运行,它就给我带来了这个错误。 terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid
这是代码:
#include<iostream>
#include<iomanip>
#include<string>
#include<conio.h>
#include<stdio.h>
using namespace std;
int prodnum, brandnum;
struct desc{
string name;
float price;
int stock;
int sold;
};
struct assets{
string prodname;
desc arr_description[8] = {0};
};
assets arr_assets[8] = {0};
void login();
int main()
{
login();
system("cls");
cout<<" ***** INVENTORY SYSTEM C++ *****"<<endl
<<"Enter Number of Products for Inventory: ";
cin>>prodnum;
for(int i = 0; i < prodnum; i++){
cout<<"Product "<<i<<": ";
cin>>arr_assets[i].prodname;
cout<<"How many "<<arr_assets[i].prodname<<"? ";
cin>>brandnum;
cout<<endl;
cout<<"Name: ";
cin>>arr_assets[i].arr_description[i].name;
cout<<endl;
cout<<"Price: ";
cin>>arr_assets[i].arr_description[i].price;
cout<<endl;
cout<<"Stock: ";
cin>>arr_assets[i].arr_description[i].stock;
cout<<"Sold: ";
cin>>arr_assets[i].arr_description[i].sold;
}
system("cls");
cout<<" ***** INVENTORY SYSTEM C++ *****\n";
cout<<"Product No."<<setw(7)<<"Product"<<setw(7)<<"Name"<<setw(7)<<"Price"<<setw(7)<<"Stock"<<setw(7)<<"Sold"<<setw(7)<<"Left\n";
for(int i = 0; i < prodnum; i++){
for(int j = 0; j < brandnum; j++){
cout<<" ["<<i<<"] "<<setw(7)
<<arr_assets[i].prodname<<setw(7)
<<arr_assets[i].arr_description[j].name<<setw(7)
<<arr_assets[i].arr_description[j].price<<setw(7)
<<arr_assets[i].arr_description[j].stock<<setw(7)
<<arr_assets[i].arr_description[j].sold<<setw(7)
<<arr_assets[i].arr_description[j].stock - arr_assets[i].arr_description[j].sold;
}
}
}
void login()
{
int attempt = 0;
bool success = false;
string correctU = "admin";
string correctP = "Exer04\r";
string username, password;
char pword[100];
while(attempt < 3 && !success){
system("cls");
cout<<"Enter Username: ";
cin>>username;
cout<<"Enter Password: ";
for(int i = 0; i < 100; i++){
pword[i] = _getch();
_putch('*');
if(pword[i] == 13){
break;
}
}
password = pword;
cout<<endl;
try{
if(username != correctU){
throw invalid_argument("Invalid Username");
}
if(password != correctP){
throw invalid_argument("Invalid Password");
}
if(username != correctU && password != correctP){
throw invalid_argument("Invalid Username and Password");
}
success = true;
}
catch(const invalid_argument& e){
cout<<"Error: "<<e.what()<<endl;
system("pause");
continue;
attempt++;
}
}
if(!success){
cout<<"Maximum Attempts Reached...";
exit(0);
}
}
我不完全知道它的结构是否有问题,或者我声明了一个字符串错误,因为我已经找了一段时间了,但我自己似乎找不到问题。 编译器对代码没有任何问题。 它编译时没有错误或警告,但程序只是因为这个错误而无法运行。
这段代码还能挽救吗? 我不知道是什么原因造成的。
只是改变这个
desc arr_description[8] = {0};
对此
desc arr_description[8];
和这个
assets arr_assets[8] = {0};
对此
assets arr_assets[8];
像assets
和desc
这样的类默认调用它们的默认构造函数。 除非你特别想要一个特定的初始值,否则你不必初始化东西。
您的代码正在做的是使用0
来初始化一个string
,在这种情况下, 0
算作一个 null 指针,这就是您收到错误消息的原因(即'basic_string::_M_construct null not valid' )。 应该清楚的是,(通常)用0
初始化 object 是没有意义的。
毫无疑问,您在= {0}
确实有意义的上下文中看到了它,但是请尝试改掉复制您不完全理解的代码的习惯,这很少能奏效。
编辑
具有讽刺意味的是。 正如评论中指出的那样,您的代码还有另一个错误,即pword
数组未终止 null,这使得将其分配给字符串时出错。 一个简单的解决这个问题的方法是写
char pword[100] = {0};
因为这会将整个数组初始化为零,因此您的数组将自动终止 null 。
一个不同的也许更好的解决方案是更改此代码
if (pword[i] == 13) {
break;
}
对此
if (pword[i] == 13) {
pword[i] = 0;
break;
}
它不仅在正确的位置添加了 null 终止符,而且还删除了密码末尾的13
字符。 显然这也意味着你必须改变
string correctP = "Exer04\r";
到
string correctP = "Exer04";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.