Mysterion
Mysterion

Reputation: 123

getting error "terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc"

This is my first post on Stackoverflow and I hope I will find a solution to my problem.

This is main of the class song, where it gets an metadata ( length, year, genre). I think the problem is coming from the function enumToString but I'm not sure :/

Song::Song(Artist artist, string title)
{
    an_artist = &artist;
    a_title = title;
}


Artist Song::artist() const
{
    return *an_artist;
}

void Song::artist(Artist artist)
{
    an_artist = &artist;
}

string Song::title() const
{
    return a_title;
}

void Song::title(string title)
{
    a_title = title;
}

Metadata *Song::metadata()
{
    return &a_metadata;
}

// converting enum to string
const string enumToString (Genre val)
{
    switch (val)
    {
        case Genre::Funk:
            return "Funk";
        case Genre::Soul:
            return "Soul";
        case Genre::Rap:
            return "Rap";
        case Genre::Rock:
            return "Rock";
        case Genre::Unknown:
            return "Unknown";
        default:
            return "Not recognized!";
    }
}

string Song::info()
{
    int minutes = a_metadata.lengthInSeconds / 60;
    int seconds = a_metadata.lengthInSeconds % 60;


    cout << "( "<< a_title << " ) " << "by " << an_artist->name()
                  << " Genre: " << enumToString(a_metadata.a_genre) << ","
                  << " Length: "<< minutes << ":" << seconds << ","
                  << " Published: " << a_metadata.publishedInYear;
    return "";
}

I'm trying to print the songs, but after the first one I get this error, and I don't really know where the problem is. This is my second time coding with C++ ^^ Thank you in advance

Moez of fawez
fawez : Moez, Sofiene, Rostom, Amine, 

( bara hakeka ) by �>��) Genre: Funk, Length: 15:0, Published: 1980
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Upvotes: 1

Views: 3193

Answers (1)

Joe Davis
Joe Davis

Reputation: 333

Note: I am posting the answer here so that one does not have to go through the comments in order to find it.

In the function "addSong" from artist.cpp:

void Artist::addSong(Song *song)
{
    the_songs.push_back(song);
    song->artist(*this); // line I will be referencing
}

You are passing the object's "this" pointer. Every object has its own "this" pointer which gives access to its own memory address. Learn more here: https://www.tutorialspoint.com/cplusplus/cpp_this_pointer.htm

However in the function "artist" from song.cpp:

void Song::artist(Artist artist)
{
    Artist artistou = artist;
}

Side note: Please use setters and getters (Encapsulation) in this scenario. I.e. void set_artist(...) and Artist get_artist().

The parameter does not reflect you passing in a pointer to the memory address of the object. Also, since artistou is declared and defined locally inside of this function, once the program leaves the scope of this function, so will this variables life leave from your computers memory. This variable should be defined in song.h as:

Artist *artistou = new Artist();

and then deleted[] from memory once no longer used as to avoid memory leaks.

Overall, please review some good coding practices on C++. As you said you are new, I am going to drop some links to some important topics that I feel you could benefit from learning.

Inheritance: https://en.cppreference.com/book/intro/inheritance

Encapsulation and Getters and Setters: https://www.w3schools.com/cpp/cpp_encapsulation.asp

Dynamic Memory Management: https://en.cppreference.com/w/cpp/memory

I hope this helped!

Upvotes: 1

Related Questions