В главе 1 мы узнали, сколько памяти выделяют системы программирования для объектов классов и структур. Не меньший интерес представляет вопрос об объеме выделяемой динамической памяти. К сожалению, стандартных средств, позволяющих выяснить размеры выделяемой памяти, практически нет. Операция sizeof () позволяет выяснить только размеры памяти, выделяемой одиночному объекту, и не может вычислить размер динамического массива. Пусть в программе определена пустая структура:
struct Empty {};
Тогда следующий фрагмент программы (Visual C++.NET 2003) выдаст на экран 1 и 1, хотя во втором случае выделено не менее 101 байта памяти:
Eapty *рЗ = new EmptyO;
cout << sizeof(*рЗ) << endl: // вывели размер
delete рЗ:
Eupty *р5 = new Empty[101]: cout << sizeof(*p5) << endl: delete[] p5:
Обычно в библиотеках любой интегрированной среды реализовано множество различных функций для работы с динамической памятью, которые не являются стандартными в С++. Мы их рассматривать не будем, за исключением одной функции — _msize(), которая позволяет узнать реальный размер выделенного блока динамической памяти. Ее прототип:
size_t _msize (void *block);
Она реализована и в Visual C++.NET 2003, и в С++ Builder 6. Используем ее для вывода размера выделяемой динамической памяти (листинг 5.1).
Листинг 5.1. Размеры динамической памяти #include <iostream>
#include <malloc.h> // для _msize()
using namespace std: //#pragma pack(l) struct Empty {}:
struct Type { int t: char ch: }; // главная функция int mainQ
{ Type *p0 = new Type():
cout << "Type = " << _msize(p0) << endl: cout << "Type =" << sizeof(*p0) << endl:: delete p0: p0 = new Type[13];
cout << HType[13]=" << _msize(p0) << endl: cout << "Type[13]=" << sizeof(*p0) << endl;; delete рв;
//
Empty *p3 = new EmptyO; cout << "Empty=" << _msize(p3) << endl; cout << "Empty=" << sizeof(*p3) << endl; delete p3;
Empty *p5 = new Empty[13]; cout << "Empty[13]=" << _msize(p5) << endl; cout << "Empty[13]=" << sizeof(*p5) << endl; delete[] p5;
Empty m[13]; cout << sizeof(m) << endl;
getchO ; return 0;
В системе Viual C++.NET 2003 эта программа в режиме выравнивания по умолчанию выдает следующие цифры:
Туре =8
Туре =8
Туре[13]=104
Туре[13]=8
Empty=l
Empty=l
Empty[13]=13
Empty[13]=l
13
Те же величины выдаются и в режиме выравнивания по границе байта. А вот в системе C++Builder 6 выдаются совсем другие числа. Без выравнивания по границе байта:
Туре =12 Туре =8
Туре[13]=104 /
Туре[13]=8.
Empty=12
Empty=8
Empty[13]=104
Empty[13]=8
104
В режиме выравнивания по байту (#pragma pack(l)):
Type =12
Type =5
Type[13]=68
ТуреШ]=5
Empty=12
Empty=l
Empty[13]=16
Empty[13]=l
13
Хотя мы не можем с уверенностью сказать, что функция _msize() показывает реально выделенный объем динамической памяти (обычно помимо памяти непосредственно для данных выделяется еще память для управляющей информации), однако даже поверхностное сравнение — в пользу Visual С++. NET 2003. |