Дополнительно
Как компилятор выделить память, не зная размер во время компиляции?
Я написал программу на C, которая принимает целочисленные входные данные от пользователя, который используется в качестве размера массива целых чисел, и используя это значение, он объявляет массив заданного размера, и я подтверждаю это проверка размера массива.
Код:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int n;
scanf("%d",&n);
int k[n];
printf("%ld",sizeof(k));
return 0;
}
и на удивление это правильно! Программа способна создать массив нужного размера. Но все статическое выделение памяти выполняется во время компиляции, а во время компиляции значение " N " не известно, так как компилятор может выделить память нужного размера?
Если мы можем выделить необходимый объем памяти просто так, то какая польза от динамической распределения с помощью функции malloc()и
метода calloc()`?
66
5
Это не "от статического распределения память". Массив
к
- это переменная, массив длина (вла), что означает, что память для этого массива выделяется во время выполнения. Размер будет определен во время выполнения значение "N".Спецификация языка не диктует какого-либо конкретного механизма распределения, но в типичной реализации своего "К", как правило, в конечном итоге просто как
int *
указатель с фактическими блок памяти выделяется на стеке во время выполнения.Для оператора вла
размер
оценивается во время выполнения, а также, который является, почему вы получаете правильное значение из него в свой эксперимент. Просто используйте%ЦУ "(а не " %ЛД
) для распечатки значений типа size_t``.Основная цель функция
malloc
(и другие функции динамического распределения памяти), чтобы переопределить рамки правил жизни, которые применимы к локальным объектам. Т. е. память, выделенная с функцияmalloc
остатки, выделенных на "вечно и", или пока вы не освободить его "свободный". Память, выделенная с функцияmalloc
не автоматически освобождается в конце блока.Вла, как в вашем примере, не дает это и"Сфера-победы над" и функциональности. Массив " к " до сих пор подчиняется обычной рамки-правила жизни: ее срок службы заканчивается в конце блока. По этой причине, в общем случае, вла не может заменить функция
malloc
и другие функции динамического выделения памяти.Но в конкретных случаях, когда вы не'т нужна, чтобы "поражение рамки" и просто пользоваться функция
malloc
, чтобы выделить время выполнения размера массива, вла действительно может рассматриваться в качестве замены для функцияmalloc
. Только имейте в виду, опять же, что Влас обычно выделяется в стеке и выделении больших кусков памяти в стеке и по сей день остается довольно сомнительной практики программирования.В C, средства, с помощью которых компилятор поддерживает Влас (переменной длины массива), компилятор - это не'т придется использовать функции malloc()
, и может (и часто делает) использовать то, что иногда называется "стек" Память - например, через систему конкретных функций, таких как
функция alloca ()`, которые не являются частью стандарта C. Если она использует стек, максимальный размер массива, как правило, значительно меньше, чем это возможно с помощью функции malloc (), потому что современные операционные системы позволяют программы гораздо меньшие квоты памяти стека.Память для массивов переменной длины, очевидно, может'т быть статически. Однако она может быть выделена на стеке. Как правило, это предполагает использование и"указатель рама и" отслеживать местоположение функции стековый фрейм в условиях динамично определены изменения указателя стека.
Когда я пытаюсь скомпилировать программу, кажется, что то, что происходит на самом деле заключается в том, что переменная длина массива получил оптимизированный выход. Поэтому я изменил код, чтобы заставить компилятор на самом деле выделить массив.
Godbolt при компиляции для ARM с помощью GCC 6.3 (с помощью рукоятки, потому что я могу прочитать руку АСМ) компилирует это https://godbolt.org/g/5ZnHfa. (мои комментарии)
Память для этой конструкции, которая называется "переменную длину массива и", вла, выделяется на стеке, по аналогии с
распределения
. Как именно это происходит, зависит именно от того, какой компилятор вы'повторно используя, но сути это's в случае расчета размера когда известно, а затем вычитания [1] общая площадь от стека-указки.Вам нужна функция
malloc
и друзей, потому что это распределение на "умирает" Когда вы покинете функцию. [И это's не действует в стандарт C++][1] для типичных процессоров, использующих стек, что "перерастает& "на ноль".
Когда он сказал, что компилятор выделяет память для переменных в компиляции, это означает, что размещение этих переменных принимается и внедряется в исполняемый код, который компилятор генерирует, а не то, что компилятор делает для них доступными в то время как он работает. Фактическое динамическое выделение памяти осуществляется автоматически программой, когда она работает.