Использование альтернативного аллокатора памяти в проекте на C/C++
4 мин
Эта статья написана прежде всего для программистов C/C++, использующих в своей работе Visual Studio 2013. Поскольку я, как говорится, totally windows guy, то я не могу оценить полезность этой статьи для программистов, не использующих эту среду в своей работе. Итак.
Не секрет, что стандартный аллокатор new/delete/malloc/free в языке C/C++ не блещет быстродействием. Конечно, всё зависит от реализации, но, если говорить об оной от компании Microsoft, то это факт. Кроме того, стандартная реализация аллокатора обладает еще одним фатальным недостатком — фрагментацией памяти. Если в вашей программе происходят частые выделения/освобождения памяти, вы можете обнаружить, что спустя несколько часов работы ваша программа упала по причине нехватки памяти, хотя свободной памяти еще достаточно — просто в результате фрагментации в пуле аллокатора не осталось свободного участка достаточного размера. (Это, кстати, абсолютно реальный случай, который произошел на одном из проектов, в котором я принимал непосредственное участие.)
Не секрет, что стандартный аллокатор new/delete/malloc/free в языке C/C++ не блещет быстродействием. Конечно, всё зависит от реализации, но, если говорить об оной от компании Microsoft, то это факт. Кроме того, стандартная реализация аллокатора обладает еще одним фатальным недостатком — фрагментацией памяти. Если в вашей программе происходят частые выделения/освобождения памяти, вы можете обнаружить, что спустя несколько часов работы ваша программа упала по причине нехватки памяти, хотя свободной памяти еще достаточно — просто в результате фрагментации в пуле аллокатора не осталось свободного участка достаточного размера. (Это, кстати, абсолютно реальный случай, который произошел на одном из проектов, в котором я принимал непосредственное участие.)

Если вы Windows-пользователь, то вам должны быть знакомы всплывающие каждый второй вторник месяца окошки, рапортующие об установке «критических обновлений безопасности». Microsoft прилагает немалые усилия, постоянно работая над исправлениями уязвимостей в своих операционных системах, но оно того стоит: в мире, где число кибератак день ото дня только возрастает, ни одна лазейка в обороне наших компьютеров не должна оставаться открытой для потенциальных злоумышленников.


Традиционно компиляторы реализуют вызовы виртуальных функций через двойную косвенную адресацию — если класс содержит хотя бы одну виртуальную функцию, то в начале каждого объекта этого класса хранится адрес таблицы виртуальных функций. Если компилятор не знает конкретный тип объекта, на который указывает указатель, то для вызова виртуальной функции нужно сначала взять указатель на объект, прочитать адрес начала таблицы, затем по номеру метода прочитать адрес, где хранится реализация функции, затем вызвать функцию.