Вопрос по arrays, c++ – Переполнение стека Visual C ++, потенциально размер массива?

0

Насколько я знаю, это не вызвано бесконечной рекурсией.

Программа работала правильно с меньшими массивами (это аудио редактор). Теперь я увеличил функциональность, чтобы учесть большие массивы (до 5 минут аудио, 26460000 фрагментов 16-битных данных ~ 50 МБ).

Поскольку увеличивается размер массива, я получаю ошибки переполнения стека в одной конкретной функции, где он должен обратить воспроизведение входного файла путем записи массива в новый массив в обратном направлении, а затем переписать исходный массив. Я предполагаю, что каждый массив может занимать до 50 МБ, в этом и заключается проблема:

<code>//initialise temporary new array to place samples in
short signed int reverse_data[max_number_samples];  

for (i=0; i<track_samples; i++)
{  //puts data from sound_data into reverse_data backwards.
  reverse_data[(max_number_samples-1)-i]=sound_data[i];    
}

for (i=0; i<track_samples; i++)    
{     //now overwrites sound_data with the data in reverse_data
  sound_data[i]=reverse_data[i];
}
</code>

Я довольно новичок в C ++ и программировании в целом, и не уверен, что ошибки, которые я получаю во время отладки, действительно говорят мне.

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

Уверены ли выreverse_data[(max_number_samples-1)-i] верно? Вы пишете данные только в конечную частьreverse_data массив, но чем вы читаете их с самого начала. Vlad
ах, я не видел этот комментарий. Вы правы, но тогда я использовал другой цикл для поиска начала аудио, и записывал только данные от начала аудио до конца. Большое спасибо за вашу помощь! holmes321

Ваш Ответ

2   ответа
6

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

Еще лучше, вы должны избегать ручного распределения и использованияstd::vector, который будет заботиться о выделении памяти. В качестве бонуса вам не нужно заботиться об освобождении. (И это современный способ C ++.)

Кстати, еслиmax_number_samples большой, возможно, вам следует выделить только столько, сколько вам нужно:

std::vector<short int> reverse_data(track_samples);

(остальная часть вашего кода остается без изменений).

Редактировать:
Еще лучшая идея: вы можете перевернуть свой массив на место, не копируя в дополнительный массив! Просто перейдите от индекса 0 к половине размера и поменяйте местамиiи(size - 1 - i)ые предметы:

for (i=0; i < track_samples/2; i++)
{
    std::swap(sound_data[i], sound_data[track_samples-1-i]);
}
Re: & quot; выделите столько, сколько вам нужно & quot ;:max_number_samples если больше чемtrack_samples, затемreverse_data[(max_number_samples-1)-i] потерпит крах, когдаi==0.
Еще лучшая идея:std::reverse(&sound_data[0], &sound_data[track_samples]);
+1 ... и не используйте рекурсию для такого большого количества данных!
@ holmes321: см. обновленный ответ.
Ах, спасибо, так что проблема заключается в размере массивов, как я и ожидал! Как бы я инициализировал свои массивы в куче, а не в стеке? holmes321
3

Как владуказалне выделяйте 50 МБ в стеке.

Но дело в том, что вам не нужно выделятьany данные. Попробуйте заменить весь фрагмент кода одним вызовомstd::reverse:

std::reverse(&sound_data[0], &sound_data[track_samples]);


Postscript: Не забудьте#include <algorithm>.

это сработало отлично, спасибо! Действительно эффективный holmes321

Похожие вопросы