Вопросы управления памятью в C++
Зачем мне надо знать что-либо о памяти?
Введение в память
Что делают с памятью
выделение памяти
-
как можно поступать - автоматический подход: сборка мусора, умные указатели против ручного подхода - new и delete
обращение к памяти
что будет, если обратиться и начать изменять значения в памяти, которая была освобождена. Жизнь после delete, жизнь после выхода из блока для автоматической переменной. Опасный г*код. delete this
тут же: почему нельзя натравить delete/free на указатель дважды? Это приведет к попытке дважды удалить адрес из списка “занятых”
Типы памяти
Str:В9. Управление памятью Sut:6.1
статическая
в ней помещаются глобальные переменные, переменные из пространств имен, статические переменные из классов и функций. Объект помещается в статическую память линкером. Объект имеет один и тот же адрес, он конструируется один раз.
Str:10.4.8. Локальная статическая память Std:3.7.1 Static storage duration
Str:10.4.9. Нелокальная память – статики и глобалы. Std: 3.6.2 Initialization of non-local objects
Автоматическая(стек)
Str:10.4.4. Локальные переменные Std:3.7.2 Automatic storage duration \
Константы
Значения данных известны во время компиляции и жестко зашиты в исполняемый файл. Если захочешь привести подобные данные const_cast'ом – ничего не выйдет. Если, обнаглев, попробуешь изменить их по указателю – получишь по башне segmentation fault'ом.
не всякая фигня, объявленная с квалификатором const, будет располагаться в области константных данных. константы в автоматической памяти, инициализируемых из аргумента функции, лежат в обычной автоматической памяти, а потому могут быть изменены после const_cast.
Динамическая/свободная
Str:10.4.5., 6.2.6 Свободная память размещаемая new. Std:3.7.3 Dynamic storage duration
Куча
Когда какой памяти надо отдавать предпочтение?
если хочешь, чтобы объект долго жил (а именно, жил после выхода из области видимости) и собираешься сам управлять его временем создания и уничтожения – динамическая.
если объект временный – автоматическая
Проблемы, связанные с памятью
memory leaks - забыл delete. Пример на работу с массивами.
фрагментация памяти. Почему бы избегаем фрагментации, а не дефрагментируем иногда память?
запись/чтение по адресам, которые тебе не принадлежат
Типы данных C++ и выделяемая память
sizeof(). Для каких типов определен Стандартом (Std:5.3.3/1), а где зависит от реализации? Какие выводы надо сделать, чтобы не попасть впросак при переходе с одной платформы на другую. Sizeof вычисляется на стадии компиляции.
чему равен sizeof структуры (Std:5.3.3/2), класса с виртуальными функциями, класса без членов-данных, union'a (Std:9.5 Unions), указателя, указателя на функцию-член, объект инстанцированного шаблона класса, разыменованного указателя на полиморфный объект, битового поля
что такое
POD-типы - ни тебе инкапсуляции, ни других ОО-фич (Std:3.9/10, 9/4)
расположение в памяти классов. Наследование, множественное наследование, виртуальное наследование. Nested-классы, local-классы - механизмы, корректирующие область видимости и к расположению в памяти не имеющие никакого отношения.
указатели на члены-данные - что они такое? А указатели на члены-функции?
Часть 2
Свойства памяти
Выравнивание
Интересные примеры по выравниванию. Как можно уменьшить размер структуры, переместив в ней поля? Выравнивание и заполнение (padding).
Например, структура Padd2a будет занимать 1 (+1) + 2 + 4 (+4)=8 байт
struct Padd2a
{
char a;
short b;
int c;
char d;
};
А структура Padd2b займет всего 1+1+2+4 байта
struct Padd2b
{
char a;
char d;
short b;
int c;
};
Endianness
что такое big-endian и little-endian
Wikipedia Википедия. Как узнать, что за порядок байтов на твоей машине?
Средства, унаследованные от C
Выделение/освобождение
malloc, free, realloc, calloc - что делают? Зачем C++-программисту знать такие вещи? Как их используют? Лулз: 20.4.6/3 The functions calloc(), malloc(), and realloc() do not attempt to allocate storage by calling ::operator new(); 20.4.6/4 The function free() does not attempt to deallocate storage by calling ::operator delete().
Почему не стоит использовать в C++?
Заполнение
Альтернативы им в C++
Std:20.4.4.1-20.4.4.3; Jos 15.2
* Fill (ForwardIterator first, ForwardIterator last, const T& value) - заполняет значением value весь промежуток Std:25.2.5
* uninitialized_fill(first,last,value) - пока не понял
* uninitialized_copy(first,last,first2) -
Мапенье
mmap
файл /proc/<num>/maps - содержит отображение памяти, смотри
man -5 proc
new/delete -- введение
Std:5.3.4/9 New
Std:5.3.5 Delete
new
delete
Разрушение объекта и очистка памяти, выделенной под него.
delete ведет себя как виртуальный при виртуальном деструкторе.
Почему нельзя натравить delete на указатель дважды?
почему можно натравить delete на нулевой указатель?
константный объект - что там ?
ссылка
Определение поведения при выделении и освобождении памяти
свои ::operator new() и ::operator delete()
Std 3.7.3.1 Allocation functions
Std: 3.7.3.2 Deallocation functions
свои operator new() и operator delete()
Когда есть смысл перегружать new/delete для классов? См. Mey:50
Как это делать?:
Какие грабли нас поджидают:
исключения
непарные new/delete
путанье глобального и локального new/delete
невиртуальныей деструктор (Sut:6.2, Dew:36)
наследование new и delete (Mey:49). Как избежать
Обработчик new - new_handler
namespace std{
typedef void (*new_handler)();
new handler set_new_handler(new_handler p) throw();
}
Std:3.7.3.1/3
An allocation function that fails to allocate storage can invoke the currently installed new_handler (18.4.2.2),
if any. [Note: A program-supplied allocation function can obtain the address of the currently installed
new_handler using the set_new_handler function (18.4.2.3).]
* описание функции находится в Std:18.4.2.3 , замечания по использованию в Mey:49,51 . Этой фу
new[] и delete []
Размещающий ::operator new
Str:10.4.11 Размещение объектов
Пример использования
ссылка на гуглкод
Когда это бывает полезно
nothrow new
Widget *wid = new (std::nothrow) Widget;
if (wid==0)
{
...
}
история возникновения - когда-то не было исключений и вместо выброса bad_alloc new возвращал нулевой указатель. Сейчас не так.
nothrow new дает только гарантии, что он сам не выбсорит исключений. Стоит выброситься исключению в конструкторе - и все будет как обычно.
Mey:49
STL
Аллокаторы
как работает обычный аллокатор? какие требования к нему предъявляются?
связанное
-
Грабли (
по идее, не стоит использовать разные распределители в одной программе). Какие аллокаторы могут улучшить произваодительность и в какх случаях?
intel tbbs,
его юзанье
-
Не знаю, куда относить
Литература
Str - Stroustroup The C++ Programming Language
Jos - Josuttis The C++ Standard Library
Std - C++ Standard ISO/IEC 14882
Sut - Sutter Exceptional C++
Dew – Stepher C.Dewhurst C++ Common Knowledge
Mey – Effective C++
Решенные вопросы
менять настоящие константы – они сидят в одной из секций ELF-файла. Обращаться к памяти, на которую ты не замапен.
пока не понимаю
Отв: Мало что, появится слово auto
вызывают malloc/free и вызывают конструктор для не-POD-типов
у нас есть typeid. Где хранится инфа о типе? Она хранится для каждого объекта? Для типа?
аллокатор, обеспечивающий thread safety
я пока не понял как делать аллокатор, да и thread safety знаю понаслышке. Устранить пробелы