LINUX.ORG.RU

[СИ] Создать большой массив

 


0

2

[СИ] Создать большой массив

Ясык СИ
ОС UNIX

Не получается создать массив больше этого:
int arr[15000000];

Это 60 000 000 байт.
А нужно 500 000 000 байт.
Определен в функции main().
Segmentation fault (core dumped)

ОЗУ 4 Гб.
Вызов k=getrlimit(RLIMIT_DATA , &rlim);
дает RLIMIT_DATA: 536870912/536870912

Top дает строку
Mem: 76M Active, 2733M Inact, 257M Wired, 1264K Cache, 112M Buf, 550M Free

Существует ли способ создать большой массив?

Кто знает прошу ответить.


malloc тебе в помощь

anonymous
()
Ответ на: комментарий от jtootf

http://www.opengroup.org/onlinepubs/009695399/functions/getrlimit.html

RLIMIT_STACK This is the maximum size of the initial thread's stack, in bytes. The implementation does not automatically grow the stack beyond this limit. If this limit is exceeded, SIGSEGV shall be generated for the thread. If the thread is blocking SIGSEGV, or the process is ignoring or catching SIGSEGV and has not made arrangements to use an alternate stack, the disposition of SIGSEGV shall be set to SIG_DFL before it is generated.

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

jtootf ★★★★★
()

> int arr[15000000];
> Определен в функции main().

я приложил ладонь к лицу, чем спрятал глаза и нос от взгляда зачинателя разговора…

пробуйте так:

static int arr[15000000];

arsi ★★★★★
()
Ответ на: комментарий от oleg_2

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

hydraulicbrakefluid
()
Ответ на: комментарий от hydraulicbrakefluid

Спасибо первому анонимусу.

oleg_2
() автор топика
Ответ на: комментарий от oleg_2

> Особенно arsi.

я предложил решение только для одного конкретного случая (массив выделяется в main). все ответы до моего комента обясняют причину и способ её устранения для остальных случаев.

arsi ★★★★★
()
Ответ на: комментарий от arsi

Я понял, что стек и статическая память.
До сих пор не приходилось спотыкаться на этом.
Я думал, что стек - это для других функций,
не main().
Опасный malloc() раньше избегал, и знаю про него мало.

Спасибо.

oleg_2
() автор топика
Ответ на: комментарий от oleg_2

>Опасный malloc() раньше избегал, и знаю про него мало.
Из всех функций стандартной библиотеки Си, и их всех его возможностей, malloc - одна из самых простых и безопасных.

Love5an
()
Ответ на: комментарий от oleg_2

> Я думал, что стек - это для других функций, не main().

да, с точки зрения организации — функция main() в си похожа на основной блок в том же паскале. но, тем не менее, это «настоящая» функция, абсолютно ничем не отличающаяся от любой другой «нормальной» функции.

> Опасный malloc() раньше избегал, и знаю про него мало.

использование malloc() сильно зависит от задачи и операционной системы. например, в системах реального времени использование malloc() часто либо ограничено, либо вообще запрещено — целевая платформа элементарно может не поддерживать heap.

да, кроме того: в линуксе не инициализированные статические данные попадают в  рай  bss. память для данных этого сегмента выделяется, как правило, по требованию. например, можете создать статический не инициализированный массив на гиг, после чего записать данные в первый, средний и последний элементы. размер RSS памяти будет увеличен, скорее всего, только на 12288 байт, т.е. три страницы по 4096 байт. другими словами, использовать malloc() (в линуксе) вместо резервирования области данных через статические области памяти на этапе компиляции часто не только не уменьшит потребление памяти, но и увеличит его (за счёт необходимости хранения локальной карты памяти).

arsi ★★★★★
()

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

Deleted
()
Ответ на: комментарий от Deleted


arsi
Статический массив инициализирован и работает.
и по top-у похоже, что он в памяти.
Как я понимаю, если static это не общее
решение, но для данной задачи правильное.
malloc() я раньше тестил в учебной программе,
но на деле применять не осмелился.
Под опасным я имел в виду утечку памяти.
Видимо надо его освоить. Для начала в
одноразовых программах (не демонах).

Спасибо.

oleg_2
() автор топика
Ответ на: комментарий от oleg_2

ээээ... а как маллок будет провоцировать утечку, если на каждый аллоцированный кусок у тебя будет соответствующий free? где тут опасность?

Deleted
()

для ваших нужд нужно динамически выделять память. один из вариантов - malloc()

connor
()
Ответ на: комментарий от oleg_2

дай дураку хрустальный х*й, так он и его разобьёт и руки порежет

поддерживаю фракцию malloc, с едиственной оговоркой: используй calloc, дабы избежать int-overflow

beastie ★★★★★
()
Ответ на: комментарий от oleg_2

Если программу можно написать так, что память выделяет только один раз при старте программы, то так её писать и надо и не использовать никаких malloc'ов. Это действительно увеличивает надежность.

Reset ★★★★★
()
Ответ на: комментарий от oleg_2

> Опасный malloc() раньше избегал, и знаю про него мало.

Следует трактовать так: «Написания программ сложнее чем Hello World я избегал и знаю про них мало».

anonymous
()
Ответ на: комментарий от beastie

> используй calloc, дабы избежать int-overflow

Какой еще int-overflow? Молодой человек, вы о чем говорите?

anonymous
()
Ответ на: комментарий от anonymous

читаем в частности malloc(3), коль наслово не верим, дядя:

     When using malloc() be careful to avoid the following idiom:

           if ((p = malloc(num * size)) == NULL)
                   err(1, "malloc");

     The multiplication may lead to an integer overflow.  To avoid this,
     calloc() is recommended.
а т.к. ТС в этом вопросе не слишком опытный — лучше подстраховаться

beastie ★★★★★
()
Ответ на: комментарий от arsi

> например, в системах реального времени использование malloc() часто либо ограничено, либо вообще запрещено — целевая платформа элементарно может не поддерживать heap.

Использование malloc как правило ограничено во встраиваемых системах с сильно ограниченным кол-вом оперативной памяти т.к. смысла в нем при таких объемах памяти нет. Библиотека языка С для таких систем может вообще не содержать как malloc'a, так и других стандартных функций.

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

anonymous
()
Ответ на: комментарий от beastie

Аргумент у malloc'a типа size_t. Если вы сами не можете правильно вычислить значение типа size_t и язык способствует таким ошибкам, то это еще не повод для использования calloc (который к тому же реализует еще и немного отличную от malloc функциональность).

anonymous
()
Ответ на: комментарий от anonymous

ну потеште, поделитесь мудростью, а то так и помру дураком

beastie ★★★★★
()
Ответ на: комментарий от arsi

> да, кроме того: в линуксе не инициализированные статические данные попадают в рай bss. память для данных этого сегмента выделяется, как правило, по требованию. например, можете создать статический не инициализированный массив на гиг, после чего записать данные в первый, средний и последний элементы. размер RSS памяти будет увеличен, скорее всего, только на 12288 байт, т.е. три страницы по 4096 байт. другими словами, использовать malloc() (в линуксе) вместо резервирования области данных через статические области памяти на этапе компиляции часто не только не уменьшит потребление памяти, но и увеличит его (за счёт необходимости хранения локальной карты памяти).

AFAIK malloc в glibc-е давно-давно выделяет память через mmap, и соответственно - если не инициализировать эту память, она так-же, будет нерезидентна и вообще, не будет заниматься. malloc(1024*1024*1024*2) отрабатывает мигом, и никак не сказывается на том, сколько в системе свободно памяти, а вот после memset-а по этому региону - память реально выделяется.

Я может немного не понял о чем вы, но простой malloc - он так-же, very efficient

hydraulicbrakefluid
()
Ответ на: комментарий от hydraulicbrakefluid

мне известно, как работает malloc в glibc :) я говорил о том, что огромные объёмы данных нет необходимости выделять динамически, особенно если их размер фиксирован. ядром страницы под такие данные и так будут выделены динамически, причём уже при обращении к массиву. т.е. если программа может завершиться так и не воспользовавшись таким мега-массивом (например, если запускали с --help, или в случае ошибки какой), то и страниц памяти от ядра она не получит.

arsi ★★★★★
()
Ответ на: комментарий от beastie

>используй calloc, дабы избежать int-overflow

ты про sizeof(size_t) = 4 ?

quest ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.