Код: Выделить всё
char* copy_string(const char* sz)
{
char ret[1024];
strcpy(ret, sz);
return ret;
}
Во-вторых, я не буду разбирать отдельно каждое твоё неверное высказывание ибо их много. Вместо этого я напишу небольшую статейку о памяти. Надеюсь, она станет полезным чтивом для тех, кто хочет знать как на самом деле обстоят дела.
Давайте начнём с простого. Сколько типов памяти у нас есть в С++? Правильный ответ "3". Это статическая, автоматическая и динамическая память. Автоматическую память иногда ещё называют стековой.
1. Статическая память выделяется под объекты еще до начала работы программы во время стартовой инициализации. Во время работы программы эту память не нужно ни захватывать, ни освобождать следовательно, все переменные расположенные в этой памяти (а это глобальные и статические переменные) имеют время жизни равное времени жизни самой программы.
2. Автоматическая память, это память, выделяемая на стеке. В неё попадают все локальные переменные, объявленные без спецификатора static.
3. Динамическая память. Её ещё называют кучей (англ. heap). Это специальная область памяти, которая не побита на кусочки с самого начала и не закреплена за определёнными переменными, подобно статической памяти. Это в полном понимании этого слова является живой "куча" от которой программа во время выполнения откусывает кусочки, использует эти их, а затем освобождает, чтобы, вполне возможно, вскоре снова захватить тот же самый кусок памяти, но использовать его под совсем другие нужды. В динамической памяти располагаются динамически создаваемые программные объекты, то есть те, для которых мы делаем new или malloc. Ещё с динамической памятью неразрывно связана такая сущность, как менеджер памяти. Это подпрограмма (фактически точкой входа в неё является системная функция malloc), которая занимается поиском и выделением указанного размера памяти в куче. По-хорошему, по менеджеру памяти следует написать отдельную статью, потому далее в эту область углубляться не будем.
Далее рассмотрим некоторые параметры переменных, расположенный в этих трёх типах памяти.
Время жизни:
1. Переменная статической памяти - время жизни программы. Здесь следует сделать заметку о локально определённых статических переменных. У них время жизни такое же, как время жизни глобальных переменных, однако у них отложена инициализация (об инициализации, кстати, я с месяц назад писал отдельную статью)
2. Переменная автоматической памяти - внутри текущего блока кода, ограниченного {}.
3. Переменная динамической памяти - от new (malloc) до delete (free).
Скорость выделения памяти:
1. Переменная статической памяти - время выделения = 0 (до входа в main она уже выделена).
2. Переменная автоматической памяти - крайне быстрое выделение (вычитание из ESP необходимого числа байт для того, чтобы разместить переменную в стеке)
3. Переменная динамической памяти - самое медленное выделение, так как идёт обращение к менеджеру памяти. Следует пробежать по куче, отыскать среди фрагментировано занятых кусков памяти диапазон байт, в которые поместится указанная переменная, затем пометить эту память, как занятую и вернуть её - это всё время.
Далее немного остановимся на плюсах и минусах.
Статическая память: казалось здесь одни плюсы. Время выделения нулевое, время жизни - пока работает программа. Однако если мы разместим все наши переменные в глобальной видимости данных или сделаем их статическими, то мы очень быстро исчерпаем всю память. Вполне возможно, что некоторые переменные, нам нужны только во время выполнения некой функции, другие на дольшее время, но всё равно содержать их на протяжении работа всей программы нецелесообразно, так как они могут быть очень-очень большими, посему освобождать их следует так быстро, как это возможно.
Автоматическая память. Из плюсов: время выделения крайне быстрое, текущий скоп можно настроить так, что как только переменная будет не нужна, она умрёт. Из минусов: то, что переменная живёт только внутри текущего блока {} это ещё и её минус. Как только нам нужно добиться того, что переменная жило за пределами текущей функции, на приходиться размещать её в в другой памяти.
Динамическая память. Из плюсов: самая гибкая память, выделить можно столько, сколько решили во время работы программы, жить объект будет вне зависимости от того в каких скобках он родился, очистить можно насильно до завершения программы. Из минусов: очень медленно выделение. Если злоупотреблять new/delete то это может стать настоящим ударом по производительности программы.