Перейти к содержимому

Какой максимальный размер массива в c

  • автор:

Максимальный размер массива

Определение типа (typedef) для типа size_t на 32-разрядных платформах (x86): unsigned int . Определение типа (typedef) для size_t на 64-разрядных платформах: unsigned __int64 .

См. также

Дополнительные ресурсы

Значок отказа согласно Закону Калифорнии о защите конфиденциальности потребителей (CCPA)

  • Светлая
  • Темная
  • Высокая контрастность
  • Предыдущие версии
  • Блог
  • Участие в доработке
  • Конфиденциальность
  • Условия использования
  • Товарные знаки
  • © Microsoft 2023

Дополнительные ресурсы

Значок отказа согласно Закону Калифорнии о защите конфиденциальности потребителей (CCPA)

  • Светлая
  • Темная
  • Высокая контрастность
  • Предыдущие версии
  • Блог
  • Участие в доработке
  • Конфиденциальность
  • Условия использования
  • Товарные знаки
  • © Microsoft 2023

Максимальный размер массива C++

Linux x86 компилятор g++. Не получается создать массив с кол-вом int элементов, пробовал даже int заменять на double все ровно пишет size of array is too large , как создать массив с максимальным кол-вом элементов? Или какой тогда максимальный размер массива? Пробовал unsigned int все ровно та же ошибка.

#include #include using namespace std; int main(int argc, char const *argv[]) < cout return 0; > 

Отслеживать
задан 27 янв 2018 в 3:05
user245380 user245380

Все конечно зависит от компилятора. Ну и от оперативной памяти. Ну а максимальная вложенность [][][] и т.д. равна 255.

27 янв 2018 в 4:08
@And пробовал больше 3-х вложенностей — ошибка
– user245380
27 янв 2018 в 5:25

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Максимальный размер массива зависит от количества доступной памяти.

Если создаёте массив на стеке (как в коде из вопроса), то память ограничена размером стека (дефолтный размер стека в линуксе можно посмотреть командой ulimit -s , его так же можно увеличить через настройки компилятора). Допустим, у вас дефолтный размер стека равен 10 Мб, тогда максимальный размер массива int32 получается 10*1024*1024 / 4 = 2621440 элементов. Но весь стек заюзать не получится, т.к. он нужен ещё и для хранения локальных переменных и параметров функций.

Если создавать массив в динамической памяти (через malloc ), то для 32-х битного приложения доступно максимум 2 Гб оперативки (но реально до 1,5 Гб можно успешно выделить). Тогда расчёты будут такими: 2*1024*1024*1024 / 4 = 536870912 элементов.

А теперь сравните полученные цифры с вашими.

Отслеживать
ответ дан 27 янв 2018 в 6:42
9,032 2 2 золотых знака 19 19 серебряных знаков 34 34 бронзовых знака

@user1 8 388 608 / sizeof(int) = 2097152 элементов. Зачем вы вообще создаете их на стеке? Стек не резиновый и полезно ограничиться 4кб. Создавайте массив в куче. Тогда максимальный размер будет определяться величиной наибольшего доступного непрерывного блока памяти и варьироваться в зависимости от фрагментации памяти.

27 янв 2018 в 7:32

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

Максимально допустимый размер массива на стеке?

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

Какой то вот такой кривой пример кода:

int Nmax = 1024; // максимально возможный размер буфера на стеке void func()< int N = . ; T p_buf[(N<=Nmax)*N]; T* p = p_buf; if(N>Nmax) p = new T[N]; . if(N>Nmax) delete [] p; > 

AntonI ★★★★
02.01.20 12:23:04 MSK
1 2 3 4 5 →

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

Deleted
( 02.01.20 12:29:18 MSK )
Ответ на: комментарий от Deleted 02.01.20 12:29:18 MSK

Я не знаю сколько нужно памяти заранее, каждый раз новый размер массива меняющийся в широких пределах.

AntonI ★★★★
( 02.01.20 12:30:46 MSK ) автор топика
Последнее исправление: AntonI 02.01.20 12:33:25 MSK (всего исправлений: 1)

Ответ на: комментарий от AntonI 02.01.20 12:30:46 MSK

В общем случае ты не можешь узнать размер стека. Си++ такой возможности не предоставляет. Из-под Линукса можешь почитать про getrlimilt(). Вроде там было что-то про размер стека. А может я и вру всё.

Deleted
( 02.01.20 12:35:52 MSK )
Ответ на: комментарий от Deleted 02.01.20 12:35:52 MSK

Вроде были какие то опции компиляции задающие размер стека? Хотя это тоже не вариант, на стеке много всего может висеть..

AntonI ★★★★
( 02.01.20 12:36:52 MSK ) автор топика

Что значит правильный? У стека конечный размер.

RazrFalcon ★★★★★
( 02.01.20 12:36:54 MSK )
Ответ на: комментарий от RazrFalcon 02.01.20 12:36:54 MSK

Правильный — что бы не превысить этот размер.

AntonI ★★★★
( 02.01.20 12:37:45 MSK ) автор топика
Ответ на: комментарий от AntonI 02.01.20 12:36:52 MSK

Вот именно.
Так что просто выдели достаточно большой буфер, котрый будет покрывать 80% твоих потребностей, а в остальных 20% выделяй память лишь на время работы функции.

Deleted
( 02.01.20 12:38:37 MSK )
Ответ на: комментарий от Deleted 02.01.20 12:35:52 MSK

Посмотрел — да, getrlimit позволяет узнать максимальный размер стека. Но все чуть хуже, мне нужно знать сколько у меня осталось свободного места на стеке, хотя и это не является решением — я же в общем случае не знаю сколько у меня уйдет памяти помимо буфера…

AntonI ★★★★
( 02.01.20 12:41:09 MSK ) автор топика
Ответ на: комментарий от Deleted 02.01.20 12:38:37 MSK

Если перефразировать — «используй свой менеджер памяти»;-)

AntonI ★★★★
( 02.01.20 12:42:11 MSK ) автор топика
Ответ на: комментарий от AntonI 02.01.20 12:42:11 MSK
Deleted
( 02.01.20 12:42:55 MSK )
Ответ на: комментарий от AntonI 02.01.20 12:41:09 MSK

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

deep-purple ★★★★★
( 02.01.20 12:43:41 MSK )
Ответ на: комментарий от Deleted 02.01.20 12:42:55 MSK

Но все таки это местами избыточно…

AntonI ★★★★
( 02.01.20 12:43:57 MSK ) автор топика
Ответ на: комментарий от AntonI 02.01.20 12:37:45 MSK
RazrFalcon ★★★★★
( 02.01.20 12:46:04 MSK )

Кажется, для кого-то настала пора задуматься не обмазаться ли аллокаторами…

jeuta ★★★★
( 02.01.20 13:02:05 MSK )

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

Tакие хотелки надо цифрами подтверждать или каким-то особенным юзкейсом, при котором априори ясно, что динамическая память не подходит. Иначе это преждевременная, и потому бесполезная, оптимизация.

А вот за такой стиль, с забором вместо ясного и понятного значения или имени переменной/константы:

T p_buf[(N<=Nmax)*N]; 

надо бить написавшего по рукам.

seiken ★★★★★
( 02.01.20 13:06:45 MSK )
Ответ на: комментарий от RazrFalcon 02.01.20 12:46:04 MSK

Ок. Осталось понять почему 2кБ а не 1 и не 4;-)

AntonI ★★★★
( 02.01.20 13:19:34 MSK ) автор топика

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

(thread_local) static + нормальный аллокатор(mmap). Либо можно пожрать говна и с вектором. Либо есть уже готовые реализация подобной дристни boost::small_vector

В крестах нет vla - поэтому либо не юзай, либо юзай аллоку.

anonymous
( 02.01.20 13:46:57 MSK )
Ответ на: комментарий от seiken 02.01.20 13:06:45 MSK

Tакие хотелки надо цифрами подтверждать или каким-то особенным юзкейсом, при котором априори ясно, что динамическая память не подходит. Иначе это преждевременная, и потому бесполезная, оптимизация.

Эти бездарные потуги запарных бездарностей. Запомни раз и навсегда - закукарекал о «преждевременная» и об «оптимизация» - определил себя за биомусор. Никто иной такой херни не несёт.

А вот за такой стиль, с забором вместо ясного и понятного значения или имени переменной/константы:

надо бить написавшего по рукам.

Нет, просто бездарное говно должно знать своё место.

anonymous
( 02.01.20 13:50:00 MSK )
Ответ на: комментарий от anonymous 02.01.20 13:50:00 MSK

С новым годом, Роман;-)

AntonI ★★★★
( 02.01.20 13:54:42 MSK ) автор топика
Ответ на: комментарий от AntonI 02.01.20 13:54:42 MSK
anonymous
( 02.01.20 13:56:31 MSK )

Максимально допустимый размер массива на стеке?

Пока не упадёт. Если мегабайт выделил, а программа не упала, значит, допустимо.

i-rinat ★★★★★
( 02.01.20 13:58:50 MSK )
Ответ на: комментарий от i-rinat 02.01.20 13:58:50 MSK

Это неконструктивный критерий - ловить такие баги при запуске на кластере довольно неприятно.

AntonI ★★★★
( 02.01.20 14:00:08 MSK ) автор топика
Ответ на: комментарий от AntonI 02.01.20 14:00:08 MSK

Не юзай мейнпоток для вычислений. Создавай потоки и руками прикручивай стек. Тогда там будет столько памяти, сколько тебе нужно. Хоть бесконечное кол-во. И уже в них запускай вычисления.

anonymous
( 02.01.20 14:03:12 MSK )
Ответ на: комментарий от anonymous 02.01.20 14:03:12 MSK

Для норм работы программы вообще желательно все ручки крутить руками, потому как обезьяны опять по мануалам говна из интернета что-то там натыкают, а потом будут ныть, что что-то не работает.

anonymous
( 02.01.20 14:04:47 MSK )

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

dave ★★★★★
( 02.01.20 14:13:14 MSK )
Ответ на: комментарий от AntonI 02.01.20 14:00:08 MSK

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

Задача похожа на арифметику для первоклассников. У Васи было десять яблок. Он отдал Пете три. Сколько яблок осталось у Васи?

Ты правда хочешь, чтобы тебе объясняли, как из десяти вычесть три?

i-rinat ★★★★★
( 02.01.20 14:17:20 MSK )
Ответ на: комментарий от i-rinat 02.01.20 14:17:20 MSK

Нет, я к сожалению не знаю ответа - иначе бы я не спрашивал.

Аналогия у приличных людей не является ни аргументом, ни доказательством.

AntonI ★★★★
( 02.01.20 14:19:54 MSK ) автор топика
Последнее исправление: AntonI 02.01.20 14:20:31 MSK (всего исправлений: 1)

Ответ на: комментарий от AntonI 02.01.20 14:19:54 MSK

Серьёзно. Не хочу слышать о приличиях от человека, который не соизволил в поисковик вбить «how to figure out stack size on linux». В первом же результате написано про uname -s и getrlimit.

i-rinat ★★★★★
( 02.01.20 14:25:11 MSK )
Ответ на: комментарий от i-rinat 02.01.20 14:25:11 MSK

AntonI ★★★★
( 02.01.20 14:38:56 MSK ) автор топика

Не понимаю, зачем тебе это и чем не угодил какой-нибудь std::vector

XMs ★★★★★
( 02.01.20 14:56:29 MSK )
Ответ на: комментарий от XMs 02.01.20 14:56:29 MSK

выделение памяти в куче - это дорогая операция

AntonI ★★★★
( 02.01.20 15:03:39 MSK ) автор топика

Будь мужиком сделай свой стэк.

pon4ik ★★★★★
( 02.01.20 15:21:00 MSK )
Ответ на: комментарий от AntonI 02.01.20 15:03:39 MSK

Ты её что, часто делаешь? Если да, у меня для тебя плохие новости. В противном случае тебе должно быть всё равно

XMs ★★★★★
( 02.01.20 15:34:15 MSK )
Ответ на: комментарий от XMs 02.01.20 15:34:15 MSK

А что то содержательное скажете?

AntonI ★★★★
( 02.01.20 15:35:26 MSK ) автор топика
Ответ на: комментарий от AntonI 02.01.20 15:03:39 MSK

выделение памяти в куче - это дорогая операция

Так выдели один раз и используй как собственный стек сколько хочешь раз.

foror ★★★★★
( 02.01.20 15:42:30 MSK )
Ответ на: комментарий от anonymous 02.01.20 13:50:00 MSK

Запомни раз и навсегда - закукарекал о «преждевременная» и об «оптимизация» - определил себя за биомусор. Никто иной такой херни не несёт.

Запомни сам, херню несешь здесь только ты.

rumgot ★★★★★
( 02.01.20 15:43:39 MSK )
Ответ на: комментарий от rumgot 02.01.20 15:43:39 MSK

В школу, отребье. Я повелитель, а ты говно.

anonymous
( 02.01.20 15:44:56 MSK )
Ответ на: комментарий от foror 02.01.20 15:42:30 MSK

Тред не читай, сразу отвечай!;-)

AntonI ★★★★
( 02.01.20 15:45:09 MSK ) автор топика

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

Harald ★★★★★
( 02.01.20 15:47:46 MSK )

Дефолтный размер стека зависит от операционной системы, по памяти в линуксе 8МиБ, на винде 1МиБ, но это всё можно крутить в обе стороны

Harald ★★★★★
( 02.01.20 15:49:02 MSK )
Ответ на: комментарий от anonymous 02.01.20 15:44:56 MSK

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

rumgot ★★★★★
( 02.01.20 15:52:42 MSK )
Ответ на: комментарий от Harald 02.01.20 15:49:02 MSK

Да, и вот тут у меня два вопроса:

  1. какие негативные последствия будут при увеличении стека?
  2. можно ли как то понять сколько памяти на стеке свободно?

AntonI ★★★★
( 02.01.20 15:54:51 MSK ) автор топика
Ответ на: комментарий от AntonI 02.01.20 15:54:51 MSK

1. Вроде никаких

2. Переносимых способов нет, можно вычесть из текущего указателя на стек начальное значение указателя на стек

Harald ★★★★★
( 02.01.20 16:01:02 MSK )
Ответ на: комментарий от Harald 02.01.20 16:01:02 MSK

  1. О! Интересно. А в чем будет заключаться непереносимость?

AntonI ★★★★
( 02.01.20 16:02:01 MSK ) автор топика
Ответ на: комментарий от AntonI 02.01.20 13:19:34 MSK

Статистика и профилирование. Первое покажет сколько кб, а второе что ты херней занимаешься.

anonymous
( 02.01.20 16:07:11 MSK )
Ответ на: комментарий от anonymous 02.01.20 13:50:00 MSK

Определяют на, а не за, пацанчик. Таких как ты в нормальной хате сразу на младшего тестировщика определяют.

anonymous
( 02.01.20 16:10:58 MSK )
Ответ на: комментарий от AntonI 02.01.20 12:36:52 MSK

При линковке.

Вроде были какие то опции компиляции задающие размер стека?

При линковке. Например, так:

gcc -Wl,--stack,9437184 -o you_app you_app.c 

Пожалуйста, стек в 9 Mb. Можно и через LD_FLAGS определить, но да, это крайне плохое решение.

Про getrlimit() тут, как я погляжу, уже написали, можно в приложении выставить свой размер стека принудительно. Примерно так (man setrlimit()):

#include int main (int argc, char **argv) < const rlim_t my_size = 9 * 1024 * 1024; /* Те же 9Mb */ struct rlimit rl; int result; result = getrlimit(RLIMIT_STACK, &rl); if (result == 0) < if (rl.rlim_cur < my_size) < rl.rlim_cur = my_size; result = setrlimit(RLIMIT_STACK, &rl); if (result != 0) < fprintf(stderr, "Error! setrlimit() returned result = %d\n", result); >> > /* Do something here. */ return 0; > 

Т.е., прямо в main() предупредили систему что Ваша приблуда работает со стеком в 9Mb и дальше просто используйте ф-ю alloca(), забыв о malloc/calloc/new и т.д. и т.п. Выставлять каждый раз заново размер стека не получится, тут нужно сразу прикинуть сколько по максимуму памяти может понадобиться. И, если на пролезет в стек, то просить у системы память под непролазящую в стек порцию данных. Т.е., высегда смотреть на размер приходящих данных – юольше 9M или меньше и, если > 9, то тогда calloc/malloc, всё как обычно.

Дополнительный профит здесь – вызов alloca() не требует очистки памяти по free(). Т.е., получили память в своей ф-ии, вышли из неё, считайте за Вами прибрано. Но и вернуть такой массив из своей ф-ии запросто не получится. А так, в принципе, этот вариант чуть быстрее и чуть экономичнее стандартного выделения памяти в куче, но и несколько менее надёжный.

В общем, тоже вариант так себе.

Moisha_Liberman ★★
( 02.01.20 16:14:25 MSK )
Последнее исправление: Moisha_Liberman 02.01.20 16:18:46 MSK (всего исправлений: 1)

Статические массивы в языке Си

При решении задач с большим количеством данных одинакового типа использование переменных с различными именами, не упорядоченных по адресам памяти, затрудняет программирование. В подобных случаях в языке Си используют объекты, называемые массивами.

Массив — это непрерывный участок памяти, содержащий последовательность объектов одинакового типа, обозначаемый одним именем.

Массив характеризуется следующими основными понятиями:

Элемент массива (значение элемента массива) – значение, хранящееся в определенной ячейке памяти, расположенной в пределах массива, а также адрес этой ячейки памяти. Каждый элемент массива характеризуется тремя величинами:

  • адресом элемента — адресом начальной ячейки памяти, в которой расположен этот элемент;
  • индексом элемента (порядковым номером элемента в массиве);
  • значением элемента.

Адрес массива – адрес начального элемента массива.

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

Размер массива – количество элементов массива

Размер элемента – количество байт, занимаемых одним элементом массива.

Графически расположение массива в памяти компьютера можно представить в виде непрерывной ленты адресов.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *