Пользователь slava упомянул следующее:
automatic
, static
, thread
и dynamic
Я будусосредоточиться на всех, кроме thread
.Он также заявил следующее:
Для C ++ не существует такой вещи, как стек или куча
Пользователь Даже Теран заявил следующее:
Я считаю, что лучший способ взглянуть на кучу против стека - это не с точки зрения «динамического» или «знания размера во время компиляции» (хотя это могут быть факторы).Вместо этого лучше всего рассматривать их с точки зрения управления временем жизни.
Вещи, выделенные в стеке, уничтожаются при выходе из области видимости.Вещи, выделенные в куче, будут существовать до тех пор, пока они не будут явно освобождены с помощью команды delete, free или delete [] (в зависимости от того, как они распределены).
Я объединю два предыдущих ответав один ответ с демонстрациями:
int main () {
int x = 5;
{ // new scope
int x = 7;
std::cout << x << '\n'; // prints 7
} // end scope
std::cout << x << '\n'; // prints 5
return 0;
}
Это считается Automatic Storage
, поскольку объявления переменных и память уничтожаются, когда они выходят из области видимости.Вы можете считать это переменной stack
в некотором смысле, поскольку в C ++ каждый function
имеет stack frame
.Эти переменные x
выше оба живут в кадре стека main.cpp
, но имеют automatic storage
.Однако при первом вызове std::cout
будет напечатано 7
, поскольку оно находится в той же области действия, что и объявленная x
переменная 2 и .Как только достигается closing
фигурная скобка }
, эта область действия уничтожается, равно как и переменная 2 nd x
.Поэтому, когда мы дойдем до следующего вызова std::cout
, будет напечатано 5
, потому что он находится в той же области действия, что и объявленный x
1 st .
int main() {
int x = 5; // Automatic storage
int* ptr = nullptr; // raw pointer
ptr = new int(x); // Dynamic Storage
std::cout << "x = " << x << '\n'; // prints 5
std::cout << "*ptr = " << *ptr << '\n'; // prints 5
{ // new scope
*ptr = 12;
} // end scope
std::cout << "x = " << x << '\n'; // x unchanged prints 5
std::cout << "*ptr = " << *ptr << '\n'; // prints 12
delete ptr; // clean up memory
return 0;
}
Dynamic Storage
живет дольше, чем область, в которой она объявлена. Вы можете передавать динамическую память из одной функции в другую, если исходный объект, на который она ссылается, остается действительным, в противном случае у вас будет утечка памяти, недействительный или зависший указатель, который можетпривести к нежелательному поведению, неопределенному поведению, аварийному завершению программы, удалению вашей ОС и запуску ядерных бомб!(Ну, последнее немного драматично; но не смейтесь, потому что плохое управление памятью приведет к хаосу в вашей кодовой базе, и ВСЕ КТО использует это!).Это позволяет вам хранить данные и изменять их из одной функции в другую, не создавая копии на их копии каждый раз, когда вам нужно ссылаться на них в каком-либо другом вычислении.
static int i = 0; // static storage: life time of application or file scope; similar to a global...
void add1() {
i++;
}
int main() {
std::cout << i << '\n';
add1();
std::cout << i << '\n';
for ( int n = 0; n < 10; n++ ) {
add1();
std::cout << "n=" << n << ": " << i << '\n';
}
return 0;
}
Выход
0
1
n=0: 2
n=1: 3
n=2: 4
n=3: 5
n=4: 6
n=5: 7
n=6: 8
n=7: 9
n=8: 10
n=9: 11
Static Storage
немного отличается.Нет необходимости очищать его как динамическую память, поскольку он имеет свойства, подобные Automatic Storage
, поскольку он будет уничтожен автоматически.Тем не менее, они обычно встречаются в global namespace
или global file space
, и они могут быть полезны, но глобальные переменные снова могут быть опасными, если не управляются или не используются должным образом.Обычно они имеют время жизни программного приложения, если оно определено в main.cpp
, или время жизни области видимости файла, если оно определено в каком-то другом файле cpp.Единственное другое отличие от Static Storage
в том, что он также инициализируется только один раз, и обычно есть только один его экземпляр!
Да, существуют различные типы классов хранения, и многие до сих пор ссылаются на нихпоскольку stack
и heap
в основном приводят к тому, что C++
был построен из C
;но значения и обычаи резко изменились за эти годы.Больше в C++
он больше связан с временем жизни и видимостью переменной, чем where
, он находится в памяти.