2013-05-04 2 views
2

У меня есть код здесь, где есть массив объектов «Бэкон». Я могу скомпилировать и запустить его и добавить объекты в массив, но когда размер массива превышает один миллион, я запустил его, и он говорит: «bacon.exe перестала работать», и мне нужно его закрыть. Я думаю, что это может быть утечка памяти, но я все еще об этом узнаю. Я использую netbeans ide, и я попытался выделить больше памяти при компиляции, но я не мог понять, как это сделать. Примечание. Это связано не только с тем, что у моего компьютера закончилась нехватка памяти, потому что у меня все еще есть 2 ГБ после запуска программы. Вот мой код:Ошибка памяти цикла C++?

#include <iostream> 
#include "Bacon.h" 
using namespace std; 

int main() { 
    const int objs = 1000000; 
    Bacon *bacs[objs]; 
    for(int i = 0;i < objs;i++){ 
     bacs[i] = new Bacon(2,3); 
    } 
     for(int i = 0;i < objs;i++){ 
     bacs[i]->print(); 
    } 
    cin.ignore(); 
    return 0; 
} 
+0

«Генерировать ошибку» не очень полезно - какая ошибка? –

+0

@PaulR извините. на самом деле не ошибка. Когда я запускаю файл .exe, он говорит: «bacon.exe перестала работать» –

+0

Вы можете посмотреть здесь http://stackoverflow.com/questions/3771154/how-to-declare-and-use-huge-arrays-of- 1-billion-integers-in-c –

ответ

6

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

Bacon **bacs = new Bacon*[objs]; 

и позже:

delete[] bacs; 
+0

Спасибо! Это сработало!!!! –

+1

Альтернативный подход - используйте 'std :: vector '. Это поддерживает изменение размера во время выполнения, которое здесь действительно не требуется, но в C++ это идиоматично предпочитает векторы для массивов. Что еще более важно, вектор фактически управляет массивом, выделенным кучей, - он обходит проблему ограничения размера стека, но вам не нужно беспокоиться о 'new' и' delete'. Недостатком является то, что массив иногда более эффективен, особенно массив в стеке, но это больше проблема для программистов с низким уровнем знаний, которые разрабатывают библиотечные контейнеры для беспокойства. – Steve314

+0

@BoogleyBeegly: Не забудьте принять этот ответ, нажав зеленую отметку под счетом слева от ответа. – Goz

1

Вы, вероятно, из стека.

Вы выделяете огромный массив указателей прямо на стек. Стек ограниченным ресурсом (обычно 8 мегабайт на процесс). Размер указателя обычно составляет 4 или 8 байт; умножьте его на миллион, и вы превысите этот предел.

+0

Извините, я не знаю, что это такое. Я ноб. –

+1

Каждая программа имеет 3 типа памяти: глобальные (выделенные один раз при запуске), динамические (выделенные с использованием 'new') и стек.В памяти стека хранятся ваши 'автоматические' переменные типа' objs' и 'bacs'. 'bacs' просто слишком велика, чтобы поместиться в стеке. Используйте 'new'. – 2013-05-04 21:46:11

+0

Ладно спасибо! Я починил это. –

0

Как я узнал, когда вы запрашиваете пространство из памяти, если операционная система, которую вы используете (в данном случае, Windows), позволяет вам ее взять, вы можете использовать и использовать это пространство.

По какой-то причине Windows не может позволить вам использовать эту память для этой ситуации. Но я не настолько эксперт в этой области. Я утверждаю это как мысль.

+0

Вы не выделяете память на стек; вы просто знаете базовый адрес и лимит. Когда регистр указателя стека (текущий верх стека) перекрывает это ограничение, происходит «ошибка стека». Эта ситуация не может быть обработана (у вас нет стека), и программа просто «перестает работать». Однако ОС может быть более информативным. – 2013-05-04 21:53:54

0

Размер стека по умолчанию (окна Visual Studio 2005, вероятно, другие держат тот же номер): 1 МБ, проверить http://msdn.microsoft.com/en-us/library/tdkhxaks%28v=vs.80%29.aspx изменить его

ULIMIT в Linux, чтобы изменить его.

Решение для кучи также действует, но в вашем примере вам не нужна куча. Запросить память кучи для ОС для чего-то, что не позволит избежать текущей функции, не является хорошей практикой. В ассемблере стек переводится просто в большее вычитание, куча запрашивается другими способами, требующими большей обработки.

+0

Что делать, если вам нужно огромное количество объектов? (Даже если вам, вероятно, никогда не понадобится больше 100000) –

+0

Ну, стек предназначен для хранения временных вещей, которые нужно забыть, когда мы вернемся к вызывающему абоненту (или, конечно же, выйдите из программного обеспечения: p), так что то же самое. Теперь, если вы не знаете, сколько места он может использовать, и у вас нет способа вычислить его, было бы более «пуленепробиваемой» использовать кучу, чтобы избежать ошибки, которую вы получили в критическом приложении, которое, не означает, что это лучшее, что нужно сделать. – elvena

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