[英]terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid (HELP)
The compiler doesn't run into any errors, but as soon as my program runs, it hits me with this error.编译器没有遇到任何错误,但是我的程序一运行,它就给我带来了这个错误。
terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid
This is the code:这是代码:
#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);
}
}
I don't exactly know if its the structures that are the problem or I declared a string wrong because I've been looking for it for a while now and I can't seem to find the problem myself.我不完全知道它的结构是否有问题,或者我声明了一个字符串错误,因为我已经找了一段时间了,但我自己似乎找不到问题。 The compiler didn't have any problems with the code.
编译器对代码没有任何问题。 It compiled with no errors or warnings but the programs just doesn't run because of this error.
它编译时没有错误或警告,但程序只是因为这个错误而无法运行。
Is this code still salvageable?这段代码还能挽救吗? I don't know what's causing it.
我不知道是什么原因造成的。
Just change this只是改变这个
desc arr_description[8] = {0};
to this对此
desc arr_description[8];
and this和这个
assets arr_assets[8] = {0};
to this对此
assets arr_assets[8];
Classes like assets
and desc
have their default constructors called by default.像
assets
和desc
这样的类默认调用它们的默认构造函数。 You don't have to initialise things unless you specifically want a particular initial value.除非你特别想要一个特定的初始值,否则你不必初始化东西。
What your code was doing was using 0
to initialise a string
, in that context 0
counts as a null pointer, and that's why you got the error message you did (ie 'basic_string::_M_construct null not valid' ).您的代码正在做的是使用
0
来初始化一个string
,在这种情况下, 0
算作一个 null 指针,这就是您收到错误消息的原因(即'basic_string::_M_construct null not valid' )。 It should be clear that it makes no sense (in general) to initialise an object with 0
.应该清楚的是,(通常)用
0
初始化 object 是没有意义的。
No doubt you saw = {0}
in a context where it did make sense, but try to get out of the habit of copying code you don't fully understand, that rarely works out.毫无疑问,您在
= {0}
确实有意义的上下文中看到了它,但是请尝试改掉复制您不完全理解的代码的习惯,这很少能奏效。
EDIT编辑
Now here's an irony.具有讽刺意味的是。 As pointed out in the comments your code has another bug in that the
pword
array is not null terminated which makes assigning it to a string an error.正如评论中指出的那样,您的代码还有另一个错误,即
pword
数组未终止 null,这使得将其分配给字符串时出错。 A simple solution to this issue is to write一个简单的解决这个问题的方法是写
char pword[100] = {0};
because that would initialise the whole array to zeros and so your array would automatically be null terminated.因为这会将整个数组初始化为零,因此您的数组将自动终止 null 。
A different and perhaps better solution would be to change this code一个不同的也许更好的解决方案是更改此代码
if (pword[i] == 13) {
break;
}
to this对此
if (pword[i] == 13) {
pword[i] = 0;
break;
}
which not only adds a null terminator in the right place, but also removes the 13
character from the end of your password.它不仅在正确的位置添加了 null 终止符,而且还删除了密码末尾的
13
字符。 Obviously this also means you would have to change显然这也意味着你必须改变
string correctP = "Exer04\r";
to到
string correctP = "Exer04";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.