Intereting Posts
Как преобразовать строку в unsigned char array в c ++ Может ли кто-нибудь дать мне пример кода _dupenv_s? Отправка матрицы с каждой итерацией: Matlab “engine.h” c ++ Как избежать дублирования кода для версий версий Внеуровневое определение конструктора в полностью специализированном шаблоне pack struct / avoid padding Встроенная функция strstr () vterg () agner Fog () Более медленный код с OpenMP, как его можно распараллелить? Как я могу использовать специализацию шаблонов для поиска типов аргументов функции-члена и т. Д.? Производительность доступа к Итератору для карты STL против вектора? Почему допустимо включать заголовочный файл дважды в c ++? Каков правильный способ инициализации статических данных в C ++ (98, 11 и 14) Короткие варианты только в boost :: program_options Как объявить указатель функции __stdcall Почему шаблон C ++ принимает массив не более специализированный, чем тот, который принимает указатель в соответствии с GCC 5.3 и Clang 4.0?

статическое и динамическое распределение памяти объектов в C ++

В C ++-программе для classа, как мы можем получить количество активных объектов в любой момент времени, которые статически создаются и динамически создаются отдельно?

К сожалению, вы просто не можете. В одной из книг Скотта Мейера есть целая секция, где он рассказывает о проблемах, связанных с попыткой достичь этого, и, если не считать этого, это невозможно.

Более эффективный C ++ – Item # 27: Требование или запрещение объектов на основе кучи.

Хорошо, вот одна из проблем, которые легко продемонстрировать (этот вопрос занимает несколько страниц, поэтому я не буду его суммировать, но здесь, по крайней мере, один вызов):

Многие (но не все) системы упорядочивают свою память следующим образом:

---------------- | Stack | | (Grows Down) | | | ---------------- | | | | | | | | | | | | ---------------- | Heap | | (Grows Up) | | | ---------------- 

Теперь вы можете подумать, что с такой конфигурацией памяти вы могли бы сделать что-то умное с оператором new / new, чтобы выяснить, находитесь ли вы в куче или не правы (проверяя, находитесь ли вы выше или ниже определенного места памяти)? Вот проблема. Там, где статические объекты идут, зависит от системы, поэтому может произойти следующее:

 ---------------- | Stack | | (Grows Down) | | | ---------------- | | | | | | | | | | | | ---------------- | Heap | | (Grows Up) | | | ---------------- | Static | | Objects | ---------------- 

Теперь вы не можете различать статические объекты и объект кучи. К сожалению! Также вы, возможно, заметили, что я сказал, что это зависит от системы, а это означает, что даже если вы должны выяснить способ отличить их, ну, ваш код не будет переносимым.

Предостережение: это использует «unedfined behavior», как описано ниже – он, как известно, работает на платформах MOST (у меня достаточно понимания, чтобы сказать, что это работает на ARM и x86 в ОС Windows, Linux и Symbian OS, и должно быть хорошо для большинства ОС, используйте «плоскую» модель памяти).

Если вы «ограничиваете» себя для конкретной системы, это может быть возможно сравнить с известным диапазоном «где стек» (и, если необходимо), где статические данные). [Можно было бы выяснить, где стек для произвольного streamа тоже, но это затрудняет задачу].

Сознавая, где находятся статические данные и стек, мы можем сравнить

 char *this_addr = static_cast(this); if (this_addr >= globa_start && this_addr <= global_end) globals++; else if (this_addr >= stacK_top && this_addr >= stack_base) stacked++; else heaped++; 

Обратите внимание, что это будет работать только в том случае, если вы сможете каким-то образом определить, где находится стек, и, конечно же, это неопределенное поведение, чтобы сравнить this с чем-либо вне того блока, в котором оно было выделено, так что технически вся концепция не определена. Тем не менее, ВОЗМОЖНО сделать это в большинстве архитектур OS / Processor. [Конечно, вам также нужно сделать то же самое, но наоборот в деструкторе]. (Он также получает «удовольствие», если вы уничтожаете объект из другого streamа, кроме того, который его создал!)

Изменить: найти стек для данного streamа не так сложно: сохранить [на stream, если есть несколько streamов], адрес локальной переменной в «первой функции» (тот, который передается в stream, создает вызов). Затем возьмите адрес переменной в текущем streamе. Все, что находится между этими значениями, находится в стеке streamов, поскольку стек представляет собой один непрерывный кусок памяти.

В качестве опции вы можете глобально перегружать новые и удалять, чтобы увеличить / уменьшить некоторый статический счетчик, что даст глобальное количество динамически распределенных объектов …

Простейшим решением для отслеживания количества активных объектов является создание диспетчера объектов (с помощью функции GetSize () или любого другого)

В classе, который вы хотите отслеживать, вы также можете добавить статическое свойство, которое будет увеличено и уменьшено в конструкторах и деструкторах соответственно.

С размером диспетчера объектов (динамическое распределение) и статическим свойством (все распределения) вы сможете получить эти номера отдельно.

Вы можете просто сказать class, передав аргумент о его местоположении:

 class LocationAware { public: enum Location { STATIC, STACK, HEAP }; explicit LocationAware(Location location) : my_location(location) { switch(location) { case STATIC: ++static_instaces; break; case STACK: ++stack_instances; break; case HEAP: ++heap_instances; break; } } ~LocationAware() { switch(my_location) { case STATIC: --static_instaces; break; case STACK: --stack_instances; break; case HEAP: --heap_instances; break; } } private: const Location my_location; public: static unsigned static_instaces; static unsigned heap_instances; static unsigned stack_instances; }; unsigned LocationAware::static_instaces = 0; unsigned LocationAware::heap_instances = 0; unsigned LocationAware::stack_instances = 0; LocationAware stat(LocationAware::STATIC); int main() { LocationAware stack(LocationAware::STACK); LocationAware * heap = new LocationAware(LocationAware::HEAP); } 

Конечно, вы можете лгать этому classу. Не.

Кроме того, если вы хотите сделать это менее навязчивым, вы можете сделать его шаблоном и использовать наследование или инкапсуляцию и использовать его из своего classа. Просто дайте ему параметр:

 template LocationAware; 

Затем либо наследуйте, либо удерживайте место в своем classе и инициализируйте его. Вы можете увидеть экземпляры, используя LocationAware::xy_instances .