Я выполняю некоторую обработку аудио и, следовательно, смешиваю некоторые C и Objective C. Я установил класс, который обрабатывает мой интерфейс OpenAL и мою обработку аудио. Я изменил суффикс класса на
.мм
…как описано в книге Core Audio среди многих примеров в Интернете.
У меня есть функция стиля C, объявленная в файле .h и реализованная в файле .mm:
static void granularizeWithData(float *inBuffer, unsigned long int total) {
// create grains of audio data from a buffer read in using ExtAudioFileRead() method.
// total value is: 235377
float tmpArr[total];
// now I try to zero pad a new buffer:
for (int j = 1; j <= 100; j++) {
tmpArr[j] = 0;
// CRASH on first iteration EXC_BAD_ACCESS (code=1, address= ...blahblah)
}
}
Странный??? Да, у меня совершенно нет идей относительно того, почему ЭТО не работает, но СЛЕДУЮЩИЙ работает:
float tmpArr[235377];
for (int j = 1; j <= 100; j++) {
tmpArr[j] = 0;
// This works and index 0 - 99 are filled with zeros
}
Кто-нибудь знает, почему я не могу объявить массив размером «total», который имеет значение int? Мой проект использует ARC, но я не понимаю, почему это может вызвать проблемы. Когда я печатаю значение «total» при отладке, это фактически правильное значение. Если у кого-то есть идеи, пожалуйста, помогите, это сводит меня с ума!
Проблема в том, что этот массив размещается в стеке, а не в куче. Размер стека ограничен, поэтому вы не можете выделить массив 235377*sizeof(float)
байтов на нем, он слишком большой. Вместо этого используйте кучу:
float *tmpArray = NULL;
tmpArray = (float *) calloc(total, sizeof(float)); // allocate it
// test that you actually got the memory you asked for
if (tmpArray)
{
// use it
free(tmpArray); // release it
}
Имейте в виду, что вы всегда несете ответственность за освобождение памяти, которая выделяется в куче, иначе вы создадите утечку.
Во втором примере, поскольку размер известен априори, компилятор резервирует это пространство где-то в статическом пространстве программы, что позволяет ему работать. Но в вашем первом примере он должен делать это на лету, что вызывает ошибку. Но в любом случае, прежде чем быть уверенным, что ваш второй пример работает, вы должны попытаться получить доступ ко всем элементам массива, а не только к первым 100.
Других решений пока нет …