При попытке проанализировать WAV-файл результаты memcpy неожиданны - PullRequest
0 голосов
/ 11 ноября 2019

Предположим, что у меня есть небольшой WAV-файл, который я открыл и выгрузил в виде массива char для обработки.

Сейчас я пытаюсь memcpy идентификатор блока fmt в4-байтовый буфер.

char fmt[4];
memcpy(fmt_chunk_id, raw_file + 12, sizeof(char) * 4);

Насколько я понимаю, memcpy это скопирует 4 байта, начиная со смещения 12, в fmt. Однако, когда я иду к отладке программы, я получаю очень странный вывод:

enter image description here

Кажется, что правильно скопирован раздел fmt, но теперьу меня почему-то куча мусора после него. Интересно, что этот мусор приходит перед форматом со смещенными байтами 0 (RIFF) и 8 (WAVE). Это файл с прямым порядком байтов (RIFF).

Не могу понять, почему я получаю данные из начала буфера в end из этого, учитывая, что я скопировал только 4 байта данных (которые должны точно соответствовать первым 4 символам f m t и пробелу).

Что здесь происходит? Выходные данные, кажется, указывают мне, что я где-то чересчур читаю память, но если бы это было так, я бы ожидал мусор, а не данные предыдущего смещения.

РЕДАКТИРОВАТЬ:

Еслиимеет значение, тип данных raw_file равен const char* const.

1 Ответ

0 голосов
/ 11 ноября 2019

Отладчик показывает область памяти, которая была динамически выделена в стеке.

Скорее всего, происходит то, что вы читаете данные из файла, и даже если вас попросят прочитать,скажем, 50 байтов, базовая система, возможно, решила прочитать больше (обычно 1024, 2048 или 4096 байтов). Таким образом, эти байты передаются в памяти, вероятно, некоторые в стеке , и этот стек теперь используется вашей функцией . Если вы попросили прочитать больше, чем эти четыре байта, то это произойдет еще с большей вероятностью.

Тогда отладчик увидит, что вы указываете на строку, но в C строки работают до тех пор, пока они не завершатся нулем(ASCIIZ). Итак, вы видите первые четыре байта и все остальное, что последовало, вплоть до первого байта 0x00 .

Если это важно для вас, просто

char fmt[5];
fmt[4] = 0;
// read four bytes into fmt.

Теперь отладчик покажет вам только первые четыре байта.

Но теперь вы понимаете, почему вы всегда должны очищать и перезаписывать конфиденциальную информацию из области памяти перед ее освобождением () - даннымимогут остаться там и даже быть использованы повторно или выброшены случайно.

...