2011-07-04 21 views
6

Tôi đang học C++ bằng cách viết chương trình chuyển đổi tệp MIDI thành Lilypond tệp nguồn. Chương trình của tôi bao gồm hai phần chính:Lỗi dường như được nêu ra bởi mã chưa được thực hiện

  • trình phân tích cú pháp tệp MIDI, tạo đối tượng có tên MidiFile.
  • trình chuyển đổi lấy đối tượng MidiFile và chuyển đổi nó thành nguồn Lilypond.

Hôm nay tôi đã bắt đầu mã hóa trình chuyển đổi, và trong khi tôi thử nghiệm lỗi lạ: chương trình chết sau khi ngoại lệ được ném, cụ thể hơn là HeaderError, điều đó có nghĩa là đoạn đầu trong tệp MIDI không như mong đợi. Nó sẽ không có vẻ lạ, nhưng lỗi này chỉ xuất hiện nếu tôi thêm một dòng mã sau mã lỗi! Tôi thêm các chính) chức năng (để giải thích rõ hơn bản thân mình

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

Với chính của tôi() như thế này, mọi thứ hoạt động đúng, nhưng, nếu tôi thêm một cái gì đó giữa buildMidiFile và vòng lặp while, hàm buildMidiFile ném ngoại lệ! !! Ngay cả khi đó là hướng dẫn hoàn toàn không liên quan!

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

Tôi không thể giải thích cho bản thân mình cách thực hiện điều này. Vì vậy, nếu bất cứ ai có ý tưởng hoặc lời khuyên, tất cả sự giúp đỡ sẽ được đánh giá rất nhiều :) Nếu nó hữu ích tôi có thể gửi mã nguồn cho các lớp khác và/hoặc chức năng.

+4

Mùi giống như một bộ nhớ ghi đè lên đâu đó trong code mà không được gọi. Bằng cách tuyên bố một biến cục bộ mới, bạn đang thay đổi bố cục ngăn xếp và các nội dung khác nhau sẽ bị ghi đè ngay bây giờ. – Torp

+0

Âm thanh như ngăn xếp tham nhũng với tôi, nhưng tôi không thể thấy ở đâu hoặc như thế nào. – Justin

+3

Điều này có thể là một vấn đề 'Parser :: Parser parser = Parser :: Parser();' vì nó tạo ra một đối tượng 'Parser' tạm thời và sao chép vào' parser'. Hãy thử chỉ với 'trình phân tích cú pháp Parser;'. –

Trả lời

3

Đã giải quyết! Như đã chỉ ra trong các ý kiến ​​cho câu hỏi, đó là một vấn đề gây ra bởi một số loại tham nhũng bộ nhớ. Như đã đề cập tôi đã sử dụng một checher bộ nhớ (valgrind) và phát hiện ra rằng đó là một lỗi thực sự ngu ngốc: tôi chỉ đơn giản quên để khởi tạo một biến trong một vòng lặp for, một cái gì đó giống như

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

và điều này dẫn đến rằng lỗi lạ: -) Khởi tạo i để 0 giải quyết vấn đề, và bây giờ chương trình làm việc với đối tượng Parser được đặt trên stack hoặc trên heap.

Vì vậy, tôi đề nghị những người khác phát sinh các sự cố tương tự khi sử dụng bộ kiểm tra bộ nhớ để kiểm soát việc sử dụng bộ nhớ của chương trình của họ. Sử dụng valgrind thực sự đơn giản:

valgrind --leak-check=yes yourProgram arg1 arg2 

nơi arg1 và arg2 là các đối số (cuối cùng) mà chương trình của bạn yêu cầu.

Ngoài việc biên dịch chương trình của bạn bằng cờ -g (ít nhất là trên g ++, tôi không biết trên các trình biên dịch khác), valgrind cũng sẽ cho bạn biết dòng mã bị rò rỉ bộ nhớ xảy ra.

Nhờ tất cả mọi người đã được trợ giúp!

Trân
Matteo

+0

Hơn nữa, với các cờ bên phải, Valgrind cũng có thể phát hiện việc sử dụng bộ nhớ chưa được khởi tạo và cho bạn biết khi nào/nơi bộ nhớ đó được cấp phát. – Novelocrat

Các vấn đề liên quan