Reputation: 231
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
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