簡體   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