Разбор файлов MIDI с использованием C - (возможная проблема выделения памяти) - PullRequest
0 голосов
/ 22 января 2019

Я пытался написать MIDI-парсер с использованием C.
Я провел свое исследование и узнал очень много о структуре файлов MIDI из нескольких источников.
Вот некоторые из наиболее полезных (для тех,которые заинтересованы):

Используя информацию из вышеперечисленных источников, я написал действительно неоптимизированный парсер MIDI.Цель текущей версии - просто напечатать, с какими событиями она столкнулась, и сохранить их в файле.
Мне удалось проанализировать MIDI-файлы [хотя я столкнулся с мета-событием, которое не должно существовать (мета-событие 0x09)].


Однако при реализации функции сохранения я видел, что некоторые миди-файлы, которые у меня были, вызывают проблемы, если я пытаюсь их сохранить (просто их анализ работает нормально) (Программа зависает дляwhile и возвращает ненулевое значение перед завершением выполнения.)
Я думаю, что проблема может быть связана с тем, как я распределяю память или обращаюсь к ней.
Вот код (Как я уже сказал, это не очень красиво)):

_MtrkCD **MtrkDatas = (_MtrkCD **)(malloc(sizeof(_MtrkCD *)));
uint64_t i,j,k,p;
for (p=0;p<MthdData->tracks_count;p++){
    MtrkDatas[p] = (_MtrkCD *)(malloc(sizeof(_MtrkCD)));
    if(!_ReadMtrkChunk(midiFile,MtrkDatas[p],p,print)){
        printf("Error reading MTrk Chunk. Bad MTrk.\n");
        return 0;
    }
}

^ часть, которая выделяет память (размещена, потому что это необходимо) ^

main.c
Вот два примера файлов, которые я использовал (один работает нормально, другой вызывает проблемы):
home.mid (Этот файл не вызывает проблем)
014-Theme03.mid (Это тот, который вызывает проблемымс)
Вот выходные данные, когда я запускаю программу:
home Parsed.txt (ожидаемый вывод)
014-Theme03 Parsed.txt (Что дажеэто?)
Опять же, я хочу отметить некоторые вещи, которые я заметил:

  1. Программа без проблем анализирует оба MIDI-файла
  2. Программа не только не может записать выходные события в файлы .txt, но также не может записать правильное количество байтов

Спасибо всем за ваше время.(Также я был бы признателен, если бы кто-то лучше отформатировал текст. Я не очень хорош в этом, как вы можете видеть.)

Обновление:

Вот рабочий код.Я сделал очень простую ошибку, выделяя память для треков.Спасибо Paul R за указание на ошибку.

_MtrkCD **MtrkDatas = (malloc(sizeof(_MtrkCD *) * (MthdData->tracks_count)));
uint64_t i,j,k,p;
for (p=0;p<MthdData->tracks_count;p++){
    MtrkDatas[p] = (malloc(sizeof(_MtrkCD)));
    if(!_ReadMtrkChunk(midiFile,MtrkDatas[p],p,print)){
        printf("Error reading MTrk Chunk. Bad MTrk.\n");
        return 0;
    }
}

1 Ответ

0 голосов
/ 22 января 2019

В этой строке:

_MtrkCD **MtrkDatas = (_MtrkCD **)(malloc(sizeof(_MtrkCD *)));

Вы выделяете только массив один указатель . Итак, здесь у вас есть неопределенное поведение:

MtrkDatas[p] = (_MtrkCD *)(malloc(sizeof(_MtrkCD)));

всякий раз, когда p> 0 (т. Е. Если track_count> 1, то у вас проблемы).

Возможно, вам следует изменить:

_MtrkCD **MtrkDatas = (_MtrkCD **)(malloc(sizeof(_MtrkCD *)));

до:

_MtrkCD **MtrkDatas = malloc(MthdData->tracks_count * sizeof(_MtrkCD *));

(обратите внимание, что приведение было удалено, поскольку оно избыточно и потенциально опасно для применения результата malloc и друзей в C ).

...