Reputation: 1
I'm sort of new to the computer coding world so I'm not exactly sure how to read the GDP, but I get Seg Fault: 11 when it tried to run my setters inside of my program. Could anyone explain why these setters are causing issues (both in lamens terms and tech terms if possible)? The setters are coded as follows:
class MapEntry{
private:
int mIDVal;
char* mKeyName;
public:
MapEntry(char *key, int val) {
mKeyName = key;
mIDVal = val;
}
int getVal(){
return mIDVal;
}
char* getKey(){
return mKeyName;
}
void setVal(int val){
this->mIDVal = val;
}
void setKey(char* key){
this->mKeyName = key;
}
};
I'm trying to create a simple database that has a char string as the key and a student ID of sorts as the val. Here is the rest of the code.
Map::Map() {
database = new MapEntry*[DATABASE_SIZE];
for (int i = 0; i < DATABASE_SIZE; i++){
database[i]->setVal(0);
database[i]->setKey("");
}
}
/* Adds (inserts) val with the associated key.
* Returns if successful or not. (It is not successful if we are out of
* memory, or if the key already exists.)
*/
bool Map::add(const char *key, int val) {
char lettersForKey[50];
strcpy(lettersForKey, key); //because const ref and all that jazz
// when adding, I need to make sure the key does not already exist
for (int i = 0; i < DATABASE_SIZE; i++)
if (database[i]->getVal() == 0) {
database[i]->setVal(val);
database[i]->setKey(lettersForKey);
}
return false;
}
void Map::print() {
for (int i = 0; i < DATABASE_SIZE; i++)
if (database[i] != NULL) {
std::cout << database[i]->getKey() << " " << database[i]->getVal() << "\n";
}
}
Upvotes: 0
Views: 813
Reputation: 87997
The errors are because you haven't created any MapEntry
objects.
This line creates an array of MapEntry pointers, but the pointers have not been initialised.
database = new MapEntry*[DATABASE_SIZE];
You need to create the MapEntry
objects as well, perhaps like this
for (int i = 0; i < DATABASE_SIZE; i++){
database[i] = new MapEntry();
database[i]->setVal(0);
database[i]->setKey("");
}
}
Of course you could avoid all the trouble by avoiding pointers, you do know that they are bad?
class Map
{
std::vector<MapEntry> database;
};
Map::Map() : database(DATABASE_SIZE)
{
for (int i = 0; i < DATABASE_SIZE; i++)
{
database[i].setVal(0);
database[i].setKey("");
}
}
No pointers, no problems. You should replace the char* mKeyName
pointer in MapEntry
with std::string mKeyName
too.
Upvotes: 5
Reputation: 409364
With
database[i]->setKey(lettersForKey);
you make the mKeyName
member point to the first element of an array that is local inside the Map::add
function. As soon as the Map::add
function exits that array goes out of scope (and basically cease to exist), and will leave you with an invalid pointer. Dereferencing that pointer will lead to undefined behavior.
If you want to handle strings, use std::string
instead.
Upvotes: 1