I'm trying to run the following code, which should get user input, place it in a string, copy that string over to an array of chars, extract the first character to another array of chars, and finally get the rest of it after a space to an array of int
s. But, it throws an error and I can't tell why:
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;
}
Think real hard about what this piece of code is doing:
temp = new char[name.size()-2];
name = name.substr(2,name.length());
name.copy(temp, name.size() + 1);
If name.size()
is less than 2 characters, the new[]
is invalid. But even if name.size()
were greater than 2, say 5, then you would allocate temp
as only 3
characters without room for the null-terminator, but then you would copy 3 characters and the null-terminator into temp
. So you are likely to corrupt memory.
That said, there are other problems with the rest of your code, too:
Your loops are going out of bounds of your ID[]
and score[]
arrays. You need to use <
instead of <=
.
You are leaking memory with your new[]
's, since you don't delete[]
the memory you allocate. In fact, there is really no need for the temp
strings at all, so you should just get rid of them completely.
You say there is a space character after the 1st character. But your use of operator>>
will not read any characters after that space, because that is where operator>>
stops reading. Use std::getline()
instead when you need to read a string with spaces in it.
Try this instead:
#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;
}
However, it would be simpler to write this without the use of std::string
at all, let operator>>
read directly into your arrays handling the spaces between them for you, eg:
#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;
}