由于尚未执行的代码显然引发了错误

时间:2011-07-04 14:40:03

标签: c++ exception memory-leaks

我正在通过编写将MIDI文件转换为Lilypond源文件的程序来学习c ++。 我的课程由两个主要部分组成:

  • 一个MIDI文件解析器,它创建一个名为MidiFile的对象。
  • 转换器,它接收MidiFile对象并将其转换为Lilypond源。

今天我开始对转换器进行编码,当我测试它时发生了一个奇怪的错误:程序在抛出异常后死亡,更具体地说是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;
}

我无法解释自己这是怎么可能的。因此,如果有人有想法或建议,所有的帮助将不胜感激:)如果它有用,我可以发布其他类和/或功能的源代码。

1 个答案:

答案 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还会告诉你内存泄漏的代码行。

感谢大家的帮助!

问候
利玛