Выделение памяти во время выполнения без ОС - PullRequest
0 голосов
/ 03 апреля 2019

В последнее время я размышлял о том, как выполняется выделение памяти во время компиляции. Насколько мне известно, компилятор выделяет фиксированное количество байтов для переменной во время компиляции. Это имеет смысл для такого утверждения:

char buffer[256];

Компилятор выделил бы 256 байт памяти для переменной, и это было бы концом этого. Если бы я хотел динамически создавать память, мне нужно было бы использовать такие функции, как malloc, предоставляемые ОС. Затем я подумал об этой функции, которая не будет использовать какие-либо функции, зависящие от ОС, но будет действовать как динамическое распределение.

*char malloc(size_t size) {
    char (*mem)[size];
    return mem;
}

Компилятор не может выделить память заранее, так как эта функция может вызываться любое количество раз во время работы программы. Как именно это будет работать? Как компилятор будет иметь дело с такой функцией? Я бы предположил, что ОС справляется с этим, но в нем не используются какие-либо функции, зависящие от ОС, что означает, что он может работать на оборудовании без ОС.

Ответы [ 2 ]

1 голос
/ 03 апреля 2019

Во-первых, *char должно быть char*, а mem не должно быть указателем ::

char* malloc(size_t size) {
    char mem[size];
    return mem;
}

Это выделяет size байтов памяти как локальную переменную в стеке. Как вы знаете, локальные переменные уничтожаются при выходе из функции. Он возвращает указатель на локальную переменную, а затем, так как функция выходит из локальной переменной, уничтожается. На практике это пространство будет повторно использоваться для локальных переменных следующего вызова функции.

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

char *mem1 = malloc(10); // using your malloc
char *mem2 = malloc(10); // using your malloc
// probably mem1 and mem2 point to the same memory now

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

char *mem1 = malloc(10); // using your malloc
strcpy(mem1, "abcde"); // if you're lucky, strcpy won't crash...
printf("Hello world.\n");
printf("mem1 contains %s\n"); // it won't be abcde because strcpy or printf overwrote the memory

Короче говоря:

Как именно это будет работать?

Не будет.

0 голосов
/ 03 апреля 2019

Чтобы сузить термин ОС - когда вы говорите «ОС», вы на самом деле имеете в виду «настольную ОС», такую ​​как Windows или Unix, которая обрабатывает не только многозадачность, но и распределение памяти, файловую систему, драйверы и т. Д., Но естьтакже являются ОСРВ, которые ничего не делают, кроме обработки многозадачности - они не заботятся о динамическом распределении памяти.

Приложения, которые не используют «настольную ОС», такие как приложения микроконтроллеров, но длякакая-то запутанная причина все равно хочет использовать malloc, выделив фиксированный объем оперативной памяти для кучи во время соединения.malloc затем правит этой областью памяти и переходит к захвату памяти, как только пожелает.В этом случае malloc реализуется и обрабатывается только библиотекой компилятора.

Это показывает, как бессмысленно использовать malloc для таких приложений.Прежде всего, встраиваемые системы не запускают несколько программ и никогда не прекращают их выполнение, поэтому бессмысленно использовать free() память - для кого вы ее освобождаете?Других программ для обмена оперативной памятью нет.Ваша программа имеет эксклюзивный доступ ко всей доступной оперативной памяти.

Таким образом, у вас есть эта фиксированная область в оперативной памяти, помеченная как куча и запрещенная для использования для всех, кроме malloc, где вы также можете хранить статически распределенные переменные вместо этого.,Это буквально пустая трата пространства.Потому что, несмотря ни на что, ваша программа должна быть в состоянии справиться с наихудшим случаем пиковых значений использования ОЗУ.В этот момент у вас должно быть определенное количество доступной памяти, независимо от того, хранится ли оно статически, в стеке или в куче.

Это означает, что любая такая программа должна заранее выделить эту точную память, иначе она сломается - ей потребуется ровно столько ОЗУ, сколько необходимо в худшем случае.И поскольку вы должны поддерживать этот наихудший случай, вы не сможете использовать эту память для других целей каким-либо разумным способом.

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

Это основная причина, почему выделение кучи никогда не используется в системах без ОС - это не имеет смысла.Я все время вижу сбитых с толку программистов, начинающих программировать на встраиваемых системах, и, прежде чем вы это знаете, они начинают использовать malloc, потому что они «не знают, сколько памяти требуется во время компиляции».Но во встроенной системе вы всегда должны это знать - вам нужно достаточно, чтобы справиться с наихудшим сценарием.И поэтому вам нужно установить фиксированные максимальные пределы для всего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...