由尚未执行的代码引发的错误

Error apparently raised by not yet executed code

本文关键字:错误 代码 执行      更新时间:2023-10-16

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

  • 一个MIDI文件解析器,它创建一个名为midfile的对象。
  • 一个接受midfile对象并将其转换为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()这样,一切正常工作,但是,如果我在buildmidfile和while循环之间添加一些东西,函数buildmidfile抛出异常!!即使它是一个完全不相关的指令!

#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;
}

我无法解释这是怎么可能的。因此,如果有人有想法或建议,所有的帮助将非常感激:)如果有帮助,我可以发布其他类和/或函数的源代码。

解决!正如在对这个问题的评论中指出的那样,这是由某种内存损坏引起的问题。正如建议的那样,我使用了内存检查器(valgrind),并发现这是一个非常愚蠢的错误:我只是忘记了在for循环中初始化变量,例如

for (int i; i < limit ; i++)
将i初始化为0解决了这个问题,现在程序可以使用放在堆栈或堆上的Parser对象。
所以我建议其他遇到类似问题的人使用内存检查器来控制他们程序的内存使用。使用valgrind非常简单:
valgrind --leak-check=yes yourProgram arg1 arg2

其中arg1和arg2是程序需要的(最终的)参数。

此外,使用-g标志编译程序(至少在g++上,我不知道在其他编译器上),valgrind还会告诉您在哪一行代码发生了内存泄漏。

感谢大家的帮助!


马特奥