Почему должен я использовать malloc () когда “символ bigchar [1u <<31 - 1]”; работает просто великолепно?

Неясно, возможно ли это в вашем случае, но моей первой реакцией на проблему такого рода обычно будет попытка переместить ее на один уровень выше лексера. То есть вместо лексера-токена NUMBER я бы вернул составляющие числа, например, {Digits}, ".", "^^" и т. Д., А затем объединить их либо в грамматику синтаксического анализатора (если он есть), либо в механизме синтаксического анализа, который вызывает лексер.

Обычный движок LR или LL на вершине может гораздо лучше справляться с прогнозом и контекстом, т. Е. В вашем примере все, что ниже Base, может уже перейти в анализатор вместо лексера.

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

7
задан Community 23 May 2017 в 12:00
поделиться

8 ответов

Well, for two reasons really:

  1. Because of portability, since some systems won't do the virtual memory management for you.

  2. You'll inevitably need to divide this array into smaller chunks for it to be useful, then to keep track of all the chunks, then eventually as you start "freeing" some of the chunks of the array you no longer require you'll hit the problem of memory fragmentation.

All in all you'll end up implementing a lot of memory management functionality (actually pretty much reimplementing the malloc) without the benefit of portability.

Hence the reasons:

  • Code portability via memory management encapsulation and standardisation.

  • Personal productivity enhancement by the way of code re-use.

14
ответ дан 6 December 2019 в 04:53
поделиться

с помощью malloc вы можете увеличивать и уменьшать массив: он становится динамическим, поэтому вы можете выделять именно то, что вам нужно.

10
ответ дан 6 December 2019 в 04:53
поделиться

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

5
ответ дан 6 December 2019 в 04:53
поделиться

Вы можете быть в состоянии разместить этот гигантский массив в одном контексте, но не в других. Например, если ваш массив является членом структуры и вы хотите передать структуру. В некоторых средах размер структуры ограничен 32 КБ.

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

2
ответ дан 6 December 2019 в 04:53
поделиться

Относительно:

После некоторых проб и ошибок я нашел выше самый большой статический массив разрешено на моей 32-битной машине Intel с GCC 4.3. Это стандарт лимит, лимит компилятора или машина limit?

Одна верхняя граница будет зависеть от того, как 4 ГБ (32-разрядное) виртуальное адресное пространство разделено между пользовательским пространством и пространством ядра. Я считаю, что для Linux наиболее распространенная схема секционирования имеет диапазон адресов 3 ГБ для пространства пользователя и диапазон адресов 1 ГБ для пространства ядра. Разделение настраивается во время сборки ядра, также используются разделения 2 ГБ / 2 ГБ и 1 ГБ / 3 ГБ. Когда исполняемый файл загружен, виртуальное адресное пространство должно быть выделено для каждого объекта независимо от того, выделена ли реальная память для его резервного копирования.

2
ответ дан 6 December 2019 в 04:53
поделиться

There is no way to free stack allocation other than going out of scope. So when you actually use global allocation and VM has to alloc you real hard memory, it is allocated and will stay there until your program runs out. This means that any process will only grow in it's virtual memory use (functions have local stack allocations and those will be "freed").

You cannot "keep" the stack memory once it goes out of scope of function, it is always freed. So you must know how much memory you will use at compile time.

Which then boils down to how many int foo[1<<29]'s you can have. Since first one takes up whole memory (on 32bit) and will be (lets lie: 0x000000) the second will resolve to 0xffffffff or thereaobout. Then the third one would resolve to what? Something that 32bit pointers cannot express. (remember that stack reservations are resolved partially at compiletime, partially runtime, via offsets, how far the stack offset is pushed when you alloc this or that variable).

So the answer is pretty much that once you have int foo [1<<29] you cant have any reasonable depth of functions with other local stack variables anymore.

2
ответ дан 6 December 2019 в 04:53
поделиться

Вы действительно должны избегать этого, если вы не знаете, что делаете. Попробуйте запросить столько памяти, сколько вам нужно. Даже если он не используется или мешает другим программам, он может испортить сам процесс. Для этого есть две причины. Во-первых, в некоторых системах, особенно в 32-битных, это может привести к преждевременному исчерпанию адресного пространства в редких случаях. Кроме того, многие ядра имеют ограничение на процессную / виртуальную / неиспользуемую память. Если ваша программа запрашивает память в моменты времени выполнения, ядро ​​может завершить процесс, если оно запрашивает зарезервированную память, превышающую этот предел. Я видел программы, которые либо зависали, либо выходили из-за сбоя malloc, потому что они резервируют ГБ памяти, используя только несколько МБ.

1
ответ дан 6 December 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: