Mihaela Miki Mihaela Miki - 12 days ago 9
C++ Question

"Your project stopped working" error when constructing an object and outputing it

Can you help me fix this run-time error? When I compile and run it, it says "your project stopped working".

This is the program. I have 2 constructors with parameters, 1 destructor, 1 copy-constructor,

operator=
,
opertator>>
and
operator<<
overloading, and accessor functions (get and set). I have to mention that for this project I create 5 classes, and the other 4 worked except this one...

#include <iostream>
using namespace std;

class Badge
{

private:
char *badgeType;
char *badgeName;
char user[50];

public:

Badge(char *type, char* name, char *user)
{
this->badgeType = new char[strlen(type) + 1];
strcpy(this->badgeType, type);
this->badgeName = new char[strlen(name) + 1];
strcpy(this->badgeName, name);
strcpy(user, user);
}

Badge(char *name, char *user)
{
this->badgeType = NULL;
this->badgeName = new char[strlen(name) + 1];
strcpy(this->badgeName, name);
strcpy(user, user);

}

Badge(const Badge &source)
{
if (source.badgeName == NULL)
this->badgeName = NULL;
else
{
this->badgeName = new char[strlen(source.badgeName) + 1];
strcpy(this->badgeName, source.badgeName);
}

if (source.badgeType == NULL)
this->badgeType = NULL;
else
{
this->badgeType = new char[strlen(source.badgeType) + 1];
strcpy(this->badgeType, source.badgeType);
}
strcpy(user, source.user);
}

~Badge()
{
if (this->badgeName)
delete[] this->badgeName;
if (this->badgeType)
delete[] this->badgeType;
}

Badge operator=(const Badge &source)
{

if (this->badgeName)
delete[] this->badgeName;

if (source.badgeName == NULL)
this->badgeName = NULL;
else
{
this->badgeName = new char[strlen(source.badgeName) + 1];
strcpy(this->badgeName, source.badgeName);
}


if (this->badgeType)
delete[] this->badgeType;

if (source.badgeType == NULL)
this->badgeType = NULL;
else
{
this->badgeType = new char[strlen(source.badgeType) + 1];
strcpy(this->badgeType, source.badgeType);
}

strcpy(user, source.user);

return *this;
}

char *getBadgeName()
{
return badgeName;
}

void setBadgeName(char *newBadgeName)
{
if (strlen(newBadgeName) == 0)
cout << "Please enter a valid name.";
else
{
delete[] badgeName;
badgeName = new char[strlen(newBadgeName) + 1];
strcpy(badgeName, newBadgeName);
}
}

char *getBadgeType()
{
return badgeType;
}

void setBadgeType(char *newBadgeType)
{
if (strlen(newBadgeType) == 0)
cout << "Please enter a valid type.";
else
{
delete[] badgeType;
badgeType = new char[strlen(newBadgeType) + 1];
strcpy(badgeType, newBadgeType);
}
}

char *getUser()
{
return user;
}

void setUser(char *newUser)
{
if (strlen(newUser) == 0)
cout << "Please enter a valid user.";
else

strcpy(user, newUser);

}

void readBadge()
{
cout << "Badge name: "<< endl;
cin >> badgeName;

cout << "Badge type: " << endl;
cin >> badgeType;

cout << "User who owns the badge: " << endl;
cin >> user;

}

void writeBadge()
{
cout << "Badge name: " << badgeName << endl;
cout << "Badge type: " << badgeType << endl;
cout << "user who owns the badge: " << user << endl;

}

friend ostream& operator<<(ostream& consola, Badge &b);
friend istream& operator>>(istream& consola, Badge &b);
};

ostream& operator<<(ostream& consola, Badge &b)
{

consola << "Badge type: " << b.getBadgeType();

consola << "Badge name: " << b.getBadgeName();

consola << "User who owns the badge: " << b.getUser();

return consola;
}

istream& operator>>(istream& consola, Badge &b)
{
cout << "Badge name: ";
char buffer[30];
consola >> buffer;
b.setBadgeName(buffer);
cout << "Badge type: ";
char buffer1[20];
consola >> buffer1[20];
b.setBadgeType(buffer1);

cout << "User who owns the badge: ";
char buffer2[20];
consola >> buffer2;
b.setUser(buffer2);

return consola;
}

int main()
{
Badge b1("Type1", "Name1", "User101");
cout << endl << b1;
return 0;
}

Answer

There is a problem in your constructor: the target and source name for the strcpy(user,user) are the same. In fact you copy the parameter content onto itself and leave the user array in the object uninitialized. This is the only place in this constructor, where you'd need a this->:

Badge(char *type, char* name, char *user)
{   
    badgeType = new char[strlen(type) + 1];
    strcpy(badgeType, type);
    badgeName = new char[strlen(name) + 1];
    strcpy(badgeName, name);
    strcpy(this->user, user);
}

Edit: as Slava mentionned in the comments, if you pass pointer or reference parameters that are not meant to be changed, you should declare them as const : this would spot these kind of subtle mismatches at compile time

Badge(const char *type, const char* name, const char *user)

Edit 2: I can't resist to suggest using string instead of char* and char[] if you are allowed: then you'd no longer have to worry about memory allocations and strcpy(). And you could rely on the default copy constructor, assignment operator and destructor.

Comments