C++ 抛出错误 "terminate called after throwing an instance of 'std::bad_alloc'"

C++ throwing error "terminate called after throwing an instance of 'std::bad_alloc'"

我正在尝试 运行 以下代码,它应该获取用户输入,将其放入一个字符串中,将该字符串复制到一个字符数组中,将第一个字符提取到另一个字符数组中,最后在 space 之后得到剩下的部分到 int 的数组。但是,它抛出一个错误,我不知道为什么:

terminate called after throwing an instance of std::bad_alloc

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main()
{
    char ID[15];
    int score[15];
    float avg[3];
    int i;

    cout<< "Hello there!:\n";

    string name;

    for (i = 0; i <= 15; i++) {

        cout<< "Please enter a ID:";
        cin >> name;

        char* temp = new char[name.size()+1];

        name.copy(temp, name.size() + 1);

        ID[i] = temp[0];

        temp = new char[name.size()-2];

        name = name.substr(2,name.length());
        name.copy(temp, name.size() + 1);

        score[i] = atoi(temp);
    }
    cout << endl;

    cout << "Name" << "      " << "Average" << endl;

    for (i = 0; i <= 15; i++) {
        cout << ID[i] << "           "<< score[i] << endl;
    }

    return 0;
}

仔细想想这段代码在做什么:

temp = new char[name.size()-2];
name = name.substr(2,name.length());
name.copy(temp, name.size() + 1);

如果name.size()小于2个字符,则new[]无效。但是即使 name.size() 大于 2,比如 5,那么您将分配 temp 作为仅 3 个字符 而没有 空终止符的空间,但随后您会将空终止符 的 3 个字符复制到 temp 中。所以你很可能会破坏内存。

也就是说,您的其余代码也存在其他问题:

  • 您的循环超出了 ID[]score[] 数组的范围。您需要使用 < 而不是 <=.

  • 您的 new[] 正在泄漏内存,因为您没有 delete[] 您分配的内存。事实上,根本不需要 temp 字符串,所以你应该完全去掉它们。

  • 你说第一个字符后有一个space字符。但是您使用 operator>> 将不会读取 space 之后的任何字符,因为那是 operator>> 停止读取的地方。当您需要读取其中包含 space 的字符串时,请改用 std::getline()

试试这个:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    char ID[15];
    int score[15];
    string name;

    cout << "Hello there!:\n";

    for (int i = 0; i < 15; ++i) {

        cout << "Please enter a ID:";
        getline(cin, name);

        ID[i] = name[0];

        name = name.substr(2,name.size());

        score[i] = atoi(name.c_str()); // <-- prefer std::stoi() instead...
    }
    cout << endl;

    cout << "Name" << "      " << "Average" << endl;

    for (int i = 0; i < 15; ++i) {
        cout << ID[i] << "           " << score[i] << endl;
    }

    return 0;
}

但是,如果完全不使用 std::string 来编写此代码会更简单,让 operator>> 直接读入您的数组,为您处理它们之间的 space,例如:

#include <iostream>
using namespace std;

int main()
{
    char ID[15];
    int score[15];

    cout << "Hello there!:\n";

    for (int i = 0; i < 15; ++i) {

        cout << "Please enter a ID:";
        cin >> ID[i];
        cin >> score[i];
    }
    cout << endl;

    cout << "Name" << "      " << "Average" << endl;

    for (int i = 0; i < 15; ++i) {
        cout << ID[i] << "           " << score[i] << endl;
    }

    return 0;
}