繁体   English   中英

在抛出“std::logic_error”实例后调用终止 what(): basic_string::_M_construct null 无效(帮助)

[英]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];

assetsdesc这样的类默认调用它们的默认构造函数。 除非你特别想要一个特定的初始值,否则你不必初始化东西。

您的代码正在做的是使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM