Matteo Ceccarello
Matteo Ceccarello

Reputation: 231

Error apparently raised by not yet executed code

I'm learning c++ by writing a program to convert MIDI files to Lilypond source files. My program is composed by two main parts:

Today I've started coding the converter, and while I was testing it a strange error occurred: the program dies after an exception being thrown, more specifically a HeaderError, that means that the header chunk in the MIDI file is not as expected. It wouldn't seem that strange, but this error shows up only if I add a line of code after the buggy code! I add the main() function to better explain myself

#include <iostream>
#include "midiToLyConverter.hpp"

int main(){

            // a queue to store notes that have not yet been shut down
    using MidiToLyConverter::Converter::NoteQueue;
            // representation of a note
    using MidiToLyConverter::Converter::Note;
            // the converter class
    using MidiToLyConverter::Converter::Converter;
            // the midifile class
    using Midi::MidiFile;
            // representation of a midi track
    using Midi::MidiTrack;
            // representation of a midi event
    using Midi::MidiEvents::Event;

    Parser::Parser parser = Parser::Parser(); // parser class
    parser.buildMidiFile(); // builds the midi file from a .mid
    Midi::MidiFile* midiFile = parser.getMidiFile(); // gets the MidiFile object

    // iterates over all the tracks in the MidiFile
    while(midiFile->hasNext()){
        std::cout<< "==========\n";
        MidiTrack* track = midiFile->nextTrack();
        // iterates over all events in a track
        while(track->hasNext()){
            Event* event = track->nextEvent();
            if (event->getEventType() == Midi::MidiEvents::NOTE_ON ||
                event->getEventType() == Midi::MidiEvents::NOTE_OFF
            )
                // print the event if it's a note on or off
                event->print();
        }
    }

    return 0;
}

With my main() like this, everything works properly, but, if I add something between buildMidiFile and the while loop, the function buildMidiFile throws the exception!!! Even if it's a completely unrelated instruction!

#include <iostream>
#include "midiToLyConverter.hpp"

int main(){

    using MidiToLyConverter::Converter::NoteQueue;
    using MidiToLyConverter::Converter::Note;
    using MidiToLyConverter::Converter::Converter;
    using Midi::MidiFile;
    using Midi::MidiTrack;
    using Midi::MidiEvents::Event;


    Parser::Parser parser = Parser::Parser(); // parser class
    parser.buildMidiFile(); // THE EXCEPTION IS THROWN HERE
    Midi::MidiFile* midiFile = parser.getMidiFile(); // gets the MidiFile object

            // adding this causes the exception to be thrown by the function
            // buildMidiFile() called 5 lines above!
    std::vector<bool>* vec = new std::vector<bool>();

    // iterates over all the tracks in the MidiFile
    while(midiFile->hasNext()){
        std::cout<< "==========\n";
        MidiTrack* track = midiFile->nextTrack();
        // iterates over all events in a track
        while(track->hasNext()){
            Event* event = track->nextEvent();
            if (event->getEventType() == Midi::MidiEvents::NOTE_ON ||
                event->getEventType() == Midi::MidiEvents::NOTE_OFF
            )
                // print the event if it's a note on or off
                event->print();
        }
    }

    return 0;
}

I can't explain myself how this is possible. So if anyone has ideas or advices, all the help would be greatly appreciated :) If it's helpful I can post the source code for other classes and/or functions.

Upvotes: 6

Views: 140

Answers (1)

Matteo Ceccarello
Matteo Ceccarello

Reputation: 231

Solved! As pointed out in comments to the question, it was a problem caused by some sort of memory corruption. As suggested I used a memory checher (valgrind) and found out that it was a really stupid error: i simply forgot to initialize a variable in a for loop, something like

for (int i; i < limit ; i++)

and this led to that strange error :-) Initializing i to 0 solved the problem, and now the program works with Parser object placed either on the stack or on the heap.

So I suggest others incurring in similar problems to use a memory checker to control the memory usage of their program. Using valgrind is really simple:

valgrind --leak-check=yes yourProgram arg1 arg2

where arg1 and arg2 are the (eventual) arguments that your program requires.

Furthermore compiling your program with the -g flag (at least on g++, I don't know on other compilers), valgrind will also tell you at wich line of code the memory leak occurred.

Thanks to everybody for the help!

Regards
Matteo

Upvotes: 3

Related Questions