我正在通过编写将MIDI文件转换为Lilypond源文件的程序来学习c ++。 我的课程由两个主要部分组成:
今天我开始对转换器进行编码,当我测试它时发生了一个奇怪的错误:程序在抛出异常后死亡,更具体地说是HeaderError,这意味着MIDI文件中的标题块不是预期。它似乎并不奇怪,但只有在我的错误代码之后添加一行代码时才出现此错误!我添加了main()函数来更好地解释自己
#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;
}
使用我的main(),一切正常,但是,如果我在buildMidiFile和while循环之间添加一些东西,函数buildMidiFile会抛出异常! 即使这是完全不相关的指令!
#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;
}
我无法解释自己这是怎么可能的。因此,如果有人有想法或建议,所有的帮助将不胜感激:)如果它有用,我可以发布其他类和/或功能的源代码。
答案 0 :(得分:3)
解决!正如对该问题的评论所指出的那样,这是由某种内存损坏引起的问题。正如建议我使用内存checher(valgrind)并发现这是一个非常愚蠢的错误:我只是忘了在for循环中初始化一个变量,比如
for (int i; i < limit ; i++)
这导致了一个奇怪的错误:-)将i初始化为0解决了问题,现在程序可以将Parser对象放在堆栈上或堆上。
因此,我建议其他人遇到类似的问题,使用内存检查程序来控制程序的内存使用情况。使用valgrind非常简单:
valgrind --leak-check=yes yourProgram arg1 arg2
其中arg1和arg2是程序所需的(最终)参数。
此外使用-g标志编译程序(至少在g ++上,我不知道在其他编译器上),valgrind还会告诉你内存泄漏的代码行。
感谢大家的帮助!
问候
利玛