C++ стек и куча в оперативной памяти

Я запускаю следующий код С++ в Ubuntu с 4 ГБ ОЗУ.

const long long  nSize = 400000000;
double Array1[nSize];
for(int i=0; i<nSize; i++)
    Array1[i]= 2*2; // store on the stack

И это умещается в оперативной памяти (и мой компьютер не жалуется). Как ни странно... htop говорит, что во время выполнения практически не используется дополнительная оперативная память... Почему? (Обычно я даю ему заснуть на 100 секунд на случай, если ему нужно будет обновиться)

С другой стороны, если я динамически выделяю огромный массив (как подобные уроки рекомендуют мне делать) -- htop сообщает мне, что он использует большую часть оперативной памяти (если не всю, и происходит сбой):

double *pnArray2 = new double[nSize];
for(int i=0; i<nSize; i++)
    pnArray2[i] = 2*2; // store on the heap

Итак, почему я должен использовать кучу для хранения больших структур данных... если (как в этом примере) стек может обрабатывать еще большие массивы?

Я думал, что куча должна быть больше, чем стек! Пожалуйста, скажите мне, где я иду так неправильно.


person Kian    schedule 19.09.2013    source источник
comment
Действительно, первый код не падает из-за отсутствия стека? Какую оптимизацию вы используете? Возможно, это оптимизация всего цикла?   -  person Mats Petersson    schedule 20.09.2013
comment
Вы пытались что-нибудь читать из массива? Если бы вы этого не сделали, возможно, компилятор все оптимизировал. Думая об этом, он может сделать это в любом случае. Попробуйте написать значения random().   -  person Elazar    schedule 20.09.2013
comment
Я на самом деле удивлен, что он даже компилируется ... Размер больше почти 3 ГБ ... [Если он не оптимизирован]   -  person Mats Petersson    schedule 20.09.2013
comment
Почему я должен использовать кучу для хранения больших структур данных? Потому что не все нетривиальные примеры кода полностью оптимизируются компилятором, включая ваши. т.е. Если бы все только этим и занимались, нам бы не о чем было беспокоиться... верно?   -  person WhozCraig    schedule 20.09.2013


Ответы (1)


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

Мне удалось воспроизвести это в MSVS 2010 в режиме выпуска и добавить простой

std::cout << Array1[42];

довел использование памяти до того же значения. (правда, я использовал более низкое значение)

Для первого фрагмента также не генерируется код, но для второго он есть.

person Luchian Grigore    schedule 19.09.2013
comment
@Элазар, может, да. Но не для меня. :) Чтобы быть уверенным, он может перебрать массив и распечатать его целиком. - person Luchian Grigore; 20.09.2013