2014-06-01 3 views
0

У меня есть ошибка в коде Arduino, который, кажется, не имеет смысла для меня. В целом, этот код будет воспроизводить музыкальные мелодии, сохраняя информацию о частоте и длительности нот, которые будут воспроизводиться на пьезо (одиночный тональный громкоговоритель). Чтобы сохранить память, я объявил/инициализировал два отдельных массива (как часть класса под названием TuneManager), который будет удерживать следующий набор частот/длительностей с двумя индексами: currentNoteIndex (который отслеживает, какая из нот будет воспроизводиться следующим образом) и loadableNoteIndex (который отслеживает следующее местоположение в массивах, которое может быть перезаписано новой записью).Несколько массивов int, указывающих на тот же адрес памяти?

int currentNoteIndex = 0; 
int loadableNoteIndex = 0; 
int tuneFreq[MAX_NOTE_BUFFER]; 
int tuneDur[MAX_NOTE_BUFFER]; 

Затем, когда приходит время, чтобы загрузить больше нот в этих массивах, я расшифровать их из строки, которая представляет собой композицию и загрузить их, как это:

tuneFreq[loadableNoteIndex] = atoi(noteFreq); 
tuneDur[loadableNoteIndex] = atoi(noteDur); 

Если я распечатать и переменных noteFreq и noteDur, я получаю ожидаемые значения. К сожалению, если я выхожу из сохраненных значений массива, я получаю неверный вывод.

Serial.print(tuneFreq[loadableNoteIndex]); 
Serial.print(" "); 
Serial.print(tuneDur[loadableNoteIndex]); 

Например, если noteFreq был 150, но noteDur был 200, выходной сигнал будет "200 200" вместо ожидаемых "150 200". Кроме того, если бы я должен был переключить порядок операторов присваивания перед печатью, он будет печатать «150 150» вместо «200 150». Это заставляет меня думать, что оба массива каким-то образом ссылаются на одни и те же адреса памяти, но я не могу понять, что пошло не так.

Если вы хотите полный код, посмотрите на TuneManager CPP и ч файлы здесь: https://github.com/bajuwa/RoboKitty/tree/TuneBuffer/EightBitTunes

ответ

0

Ваши массивы неправильно объявлены в заголовке:

private: 
    int tuneFreq[]; 
    int tuneDur[]; 

Это декларирует два нулевых размера массивов (даже если вы выделяете массивы в исходном файле, это не имеет значения), что является незаконным (для них используется некоторый компилятор, такой как GCC)

Вы должны объявить размер в заголовке, чтобы сообщить компилятору сущность е ваш типа:

private: 
    const int MAX_NOTE_BUFFER = 25; 
    int tuneFreq[MAX_NOTE_BUFFER]; 
    int tuneDur[MAX_NOTE_BUFFER]; 

Вашей программа в настоящее время имеет неопределенное поведение (ваши пишут мимо конца «массив»), поэтому все, что вы наблюдаете (вы по сути письма в некоторую память прошлого вашего объекта) может считаются случайными.

Тот факт, что вы пишете два раза в том же месте (массив нулевого размера имеет размер ... ноль), объясняет, почему он выглядит так: «оба массива имеют один и тот же адрес», но с неопределенным поведением, что-либо иначе может случиться.

+0

Это не нулевой размер, это [незаконно] (http://coliru.stacked-crooked.com/a/6aedd892f0c459c2). – chris

+0

Спасибо! Это сделало замечательную работу по лечению моей головной боли. X) Я был настолько сосредоточен на совпадении всего этого, что я даже не думал о файле заголовка. Xx – bajuwa

+0

Разрешено с gcc: https://gcc.gnu.org/onlinedocs/ gcc/Zero-Length.html, но Ill edit. – quantdev

Смежные вопросы