Я понимаю, что могу предоставить собственный распределитель для большинства стандартных контейнеров. Если я записываю распределение памяти в этом специальном распределителе, я могу отслеживать распределение памяти. Например, с помощью MyAllocator в std::vector мы всегда можем узнать, сколько памяти потребляет этот вектор.
Однако такие распределители применимы только к стандартным контейнерам. Если мы хотим отслеживать пользовательский класс, нам нужно придумать некоторые другие идеи.
Одна из идей заключается в том, что мы можем переопределить оператор new и оператор new [] . Однако есть и недостатки:
и оператор new [] применяются только к выделениям с помощью операторов new, которые обычно распределяют пространство в куче. Хорошо, возможно, это не такая уж большая проблема, поскольку мы больше всего заботимся о куче памяти.
и оператор new [] не применяются к динамическому выделению памяти внутри класса. Например, для данного типа T, если я выделил некоторую память с помощью a = new R [10000] в T::T(), то такое выделение памяти не будет отслеживаться оператором new и оператор new [] для T.
Подробнее поговорим о верхнем регистре. Проблема существует, даже если я также реализовал оператор new из R. Потому что это позволяет мне только суммировать, сколько памяти выделяет T и сколько памяти R выделяет соответственно. Однако я хочу знать, сколько памяти T выделяет, включая все его поля, в определенный момент времени. Это означает, что если я вызвал a = new R [10000], то я каким-то образом смогу обнаружить, что экземпляр T выделил sizeof(T) + sizeof(R) * 1000 вместо того, чтобы экземпляр T выделил sizeof(T), а еще 1000 экземпляров R выделили sizeof(R).
Я понимаю, что могу предоставить собственный распределитель для большинства стандартных контейнеров. Если я записываю распределение памяти в этом специальном распределителе, я могу отслеживать распределение памяти. Например, с помощью MyAllocator в std::vector мы всегда можем узнать, сколько памяти потребляет этот вектор. Однако такие распределители применимы только к стандартным контейнерам. Если мы хотим отслеживать пользовательский класс, нам нужно придумать некоторые другие идеи. Одна из идей заключается в том, что мы можем переопределить оператор new и оператор new [] . Однако есть и недостатки: [list] [*][code]operator new[/code] и оператор new [] применяются только к выделениям с помощью операторов new, которые обычно распределяют пространство в куче. Хорошо, возможно, это не такая уж большая проблема, поскольку мы больше всего заботимся о куче памяти.
[*][code]operator new[/code] и оператор new [] не применяются к динамическому выделению памяти внутри класса. Например, для данного типа T, если я выделил некоторую память с помощью a = new R [10000] в T::T(), то такое выделение памяти не будет отслеживаться оператором new и оператор new [] для T.
[*]Подробнее поговорим о верхнем регистре. Проблема существует, даже если я также реализовал оператор new из R. Потому что это позволяет мне только суммировать, сколько памяти выделяет T и сколько памяти R выделяет соответственно. Однако я хочу знать, сколько памяти T выделяет, включая все его поля, в определенный момент времени. Это означает, что если я вызвал a = new R [10000], то я каким-то образом смогу обнаружить, что экземпляр T выделил sizeof(T) + sizeof(R) * 1000 вместо того, чтобы экземпляр T выделил sizeof(T), а еще 1000 экземпляров R выделили sizeof(R).