2013-06-10 5 views
4

Я использую Dev C++ для написания программы моделирования. Для этого мне нужно объявить одномерный массив с типом данных double. Он содержит 4200000 элементов - например, double n[4200000].Объявление большого массива на стек

Компилятор не обнаруживает ошибки, но программа завершает выполнение. Я проверил, и программа отлично работает для массива, содержащего 5000 элементов.

Теперь я знаю, что объявление такого большого массива в стеке не рекомендуется. Однако дело в том, что для моделирования требуется, чтобы я вызывал определенные элементы из массива несколько раз - например, мне может понадобиться значение n[234] или n[46664] для данного расчета. Поэтому мне нужен массив, в котором легче просеивать элементы.

Есть ли способ объявить этот массив в стеке?

+0

Для Linux/GCC см http://stackoverflow.com/questions/2279052/increase-stack-size -in-linux-with-setrlimit, для Windows/gcc, см. http://stackoverflow.com/questions/156510/increase-stack-size-on-windows-gcc и для MSVC, http://msdn.microsoft. com/en-us/library/tdkhxaks% 28v = vs.110% 29.aspx - см. там. –

+3

Я не думаю, что вы можете использовать 'std :: vector ar (4200000);'? Остальное использует обычный регулярный массив для индексирования и т. Д. – WhozCraig

+3

Непонятно, почему этот массив должен находиться в стеке. Он будет работать так же хорошо, когда вы выделите его из кучи. –

ответ

8

Нет, нет (мы будем говорить «разумный») способ объявить этот массив в стеке. Однако вы можете объявить указатель в стеке и отбросить немного памяти в куче. не

double *n = new double[4200000]; 

доступа к п [234] это, должно быть быстрее, чем доступ к п [234] массива, который вы объявили, как это:

double n[500]; 

Или еще лучше, вы могли бы использовать векторы

std::vector<int> someElements(4200000); 
someElements[234];//Is equally fast as our n[234] from other examples, if you optimize (-O3) and the difference on small programs is negligible if you don't(+5%) 

Что, если вы оптимизируете с помощью -O3, так же быстро, как массив, и намного безопаснее. Как и в растворе

double *n = new double[4200000]; 

вы утечка памяти, если вы этого не сделаете:

delete[] n; 

И с исключениями и различных вещей, это очень небезопасно способ делать вещи.

0

Есть ли какие-либо причины, по которым вы хотите это сделать в стеке?

Я спрашиваю, потому что следующее даст вам конструкцию, которая может быть использована аналогичным образом (особенно доступ к значениям с использованием array[index]), но она намного менее ограничена по размеру (общий максимальный размер в зависимости от 32 бит/64 бит модель памяти и доступная память (оперативная память и память подкачки)), поскольку она выделена из кучи.

int arraysize= 4200000; 
int *heaparray= new int[arraysize]; 

... 

k= heaparray[456]; 

... 

delete [] heaparray; 

return; 
+0

Вам понадобятся некоторые комментарии о том, как ваш код исправляет проблему ... –

+0

Я бы переключил доступный RAM в доступную память, так как файл страницы и swap-пространство также должны учитываться. – ChrisCM

+2

@MM Я просто так привык, как и все здесь: сделайте причудливый ответ быстрым, а затем отредактируйте его, сделав комментарии, потому что я слишком часто получаю хороший ответ сразу и получаю три быстрых ответа в очереди впереди. – Nicholaz

2

Да, вы можете объявить этот массив в стеке (с небольшой дополнительной работой), но это не разумно.

Невозможно обосновать причину, по которой массив должен находиться в стеке.

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

В любом случае, просто не делайте этого.

Если вы настаиваете, что вы должны выделить массив в стеке, вам нужно будет зарезервировать 32 мегабайта пространства стека сначала (желательно немного больше). Для этого, используя Dev-C++ (который предполагает Windows + MingW), вам нужно либо установить зарезервированный размер стека для вашего исполняемого файла, используя флаги компилятора, такие как -Wl,--stack,34000000 (это составляет несколько больше, чем 32MiB), или создать поток (который позволяет вам укажите зарезервированный размер стека для этого потока).
Но на самом деле, снова, просто не делайте этого. Нет ничего плохого в динамическом распределении огромного массива.

+0

Интеллектуальное любопытство, я бы хотел увидеть этот метод. Если вы не хотите предоставлять его здесь (чтобы не дать кому-то инструмент, который они не готовы использовать), вы можете начать чат со мной! Или просто отправьте фразу Google, которая указывает мне в правильном направлении. – ChrisCM

+0

Ах, компиляторные флаги ... это обман! :) Хотя, я думаю, что если вы используете потоки, вы можете на самом деле сделать это и в коде ... – ChrisCM

+0

@ChrisCM: Да, если вы создаете поток только для этого, вы можете сделать это чисто программно ... но это просто безумный по сравнению с использованием 'operator new []', который был просто _made_ для такого рода задач. – Damon

7

Вы можете увеличить размер стека. Попробуйте добавить эти опции для ваших флагов ссылка:

-Wl,--stack,36000000

Это может быть слишком большим, хотя (. Я не уверен, если Windows, устанавливает верхний предел на размер стека) В действительности, хотя, вы не должны делать, что даже если он работает. Используйте динамическое распределение памяти, как указано в других ответах.

(Weird, писать ответ и надеюсь, что это не будут приняты ... :-P)

+0

+1 за последнее предложение! Пожалуйста, ради любви к Богу, если вы не понимаете, почему новые или векторные решения так же хороши, как статически распределенные массивы, просто используйте их вслепую и забывайте, что это сообщение когда-либо существовало! – ChrisCM

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