Получение исключения при объявлении большого массива

Следующий код генерирует ошибку для меня

int main(int argc, char* argv[])
{
    int sieve[2000000];
    return 0;
}

Как мне обойти это? Я использую Turbo С++, но хочу сохранить свой код в C

EDIT:

Спасибо за совет. Код, приведенный выше, был только, например, я фактически объявляю массив в функции, а не в sub main. Кроме того, мне нужен был массив, который должен быть инициализирован нулями, поэтому, когда я googled malloc, я обнаружил, что calloc идеально подходит для моих целей.

Malloc/calloc также имеет преимущество перед распределением в стеке, позволяя мне объявить размер с помощью переменной.

Ответы

Ответ 1

Ваш массив слишком велик, чтобы вписаться в стек, подумайте об использовании кучи:

int *sieve = malloc(2000000 * sizeof(*sieve));

Если вы действительно хотите изменить размер стека, взгляните на этот документ.

Совет. - Не забудьте освободить динамически выделенную память, если она больше не нужна.

Ответ 2

Есть 3 способа:

  • Выделите массив в куче - используйте malloc(), как предполагали другие плакаты. Не забывайте free() его (хотя для main() это не так уж важно - ОС будет очищать память для вас при завершении программы).
  • Объявить массив на уровне единицы - он будет выделен в сегменте данных и доступен для всех (добавление static в объявление ограничит видимость для единицы).
  • Объявите свой массив как static - в этом случае он будет выделен в сегменте данных, но будет видимым только в main().

Ответ 3

int main(void)
{
    int *sieve = xmalloc(2000000 * sizeof(int));
    /* do stuff */
    free(sieve);
    return 0;
}

Ответ 4

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

int main(int argc, char* argv[])
{
    int * sieve;
    sieve = malloc(20000);
    return 0;
}

Ответ 5

Это около 7 МБ пространства стека. В визуальной студии вы должны использовать /STACK: ###, ###, чтобы отобразить нужный размер. Если вы действительно хотите огромный стек (это может быть веской причиной, используя LISP или что-то еще:)), даже куча ограничена небольшими ассигнованиями, прежде чем заставить вас использовать VirtualAlloc), вы также можете установить PE с помощью /LARGEADDRESSAAWARE (компоновщик Visual Studio снова), но это сконфигурирует ваш PE-заголовок, чтобы позволить вашему скомпилированному двоичному файлу обращаться к полному 4 ГБ 32-битного адресного пространства (если он работает в WOW64). Если вы создаете действительно массивные двоичные файлы, вам также, как правило, нужно будет сконфигурировать /bigobj в качестве дополнительного параметра-линкера.

И если вам все еще нужно больше места, вы можете радикально нарушить соглашение, используя что-то simular to (снова ссылку MSVC)/merge:, что позволит вам упаковать один раздел в другой, так что вы можете использовать каждый отдельный байт для единый общий код/​​раздел данных. Естественно, вам также нужно будет настроить разрешения SECTIONS в файле def или с помощью #pgrama.

Ответ 6

Использовать malloc. Все проверки типа возвращаемого значения не являются нулевыми, если оно равно нулю, то ваша система просто не имеет достаточной памяти, чтобы соответствовать многим значениям.

Ответ 7

Есть ли какая-то причина, по которой вы не можете использовать alloca() для выделения необходимого пространства в фрейме стека в зависимости от того, насколько большой объект действительно должен быть?

Если вы это сделаете и все еще наложите стек, поместите его в выделенную кучу. Я настоятельно рекомендую НЕ объявлять его как static в main() и помещать его в сегмент данных.

Если он действительно должен быть таким большим, и ваша программа не может выделить его в кучу, на самом деле у вашей программы нет бизнеса, работающего на этом типе машины.

Что (точно) вы пытаетесь выполнить?

Ответ 8

Ваш массив огромен.

Возможно, ваш компьютер или ОС не имеют или не хотят выделять столько памяти.


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

Преимущество malloc заключается в том, что он пытается выделить память в куче вместо стека (поэтому вы не получите переполнение стека).

Вы можете проверить значение, возвращаемое malloc, чтобы увидеть, было ли выделение успешным или неудачным. Если это не удается, просто попробуйте malloc меньшего массива.


Другой вариант - использовать другую структуру данных, которая может быть изменена "на лету" (например, связанный список). Wether этот вариант хорош, зависит от того, что вы собираетесь делать с данными.

Еще одним вариантом было бы хранить вещи в файле, передавая данные "на лету". Этот подход является самым медленным.

Если вы заходите на хранение на жесткий диск, вы можете также использовать существующую библиотеку (для баз данных)

Ответ 9

Поскольку Turbo C/С++ - это 16-битный тип данных компилятора, потребляет около 2 байтов. 2 байта * 2000000 = 40 000 000 байт = 3,8147 МБ пространства.

Автоматические переменные функции хранятся в стеке, что приводит к переполнению памяти стека. Вместо этого используйте память данных [используя статическую или глобальную переменную] или динамическую память кучи [с помощью malloc/calloc] для создания необходимой памяти в соответствии с доступностью отображения памяти процессора.

Ответ 10

Для установки размера стека должна быть опция someplace.

Ответ 11

Используйте malloc вместо этого. Синтаксис:

newnode=(struct node *)malloc(sizeof(struct node))