Управление памятью и куча отладки
Обновлен: Ноябрь 2007
Этот раздел применим для следующих версий.
Выпуск |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Экспресс-выпуск |
Только машинные коды |
|||
Standard |
Только машинные коды |
|||
Pro и Team |
Только машинные коды |
Условные обозначения:
Применимо |
|
Неприменимо |
|
Команда или команды по умолчанию скрыты. |
Две самые распространенные и трудноразрешимые проблемы, с которыми сталкиваются программисты, — это перезапись конца выделенного буфера и утечки памяти (невозможность освободить выделенную память, когда она уже не нужна). Отладочная куча предоставляет мощные средства для решения подобных проблем с памятью.
Версии отладки функций кучи
Отладочные версии функций кучи вызывают стандартные или базовые версии, используемые в окончательных построениях. Когда запрашивается блок памяти, диспетчер отладочной кучи выделяет из основной кучи блок памяти немного больше требуемого, и возвращает указатель на часть этого блока. Например, допустим, приложение содержит вызов: malloc( 10 ). В окончательном построении malloc вызовет базовую программу выделения памяти в куче, которая запросит выделение 10 байтов. А в отладочном построении malloc вызовет _malloc_dbg, который затем уже сам вызовет базовую программу выделения памяти в куче и запросит выделение 10 байтов и около 36 байтов дополнительно. Все результирующие блоки памяти в отладочной куче подключаются к единому связанному списку, который упорядочивает их по времени выделения.
Дополнительная память, выделяемая программами выделения памяти в куче, используется для учета используемых системных ресурсов, для указателей, связывающих отладочные блоки памяти вместе, и для небольших буферов с обеих сторон данных для перехватывания перезаписи выделенной области.
На текущий момент структура заголовка блока, используемая для хранения данных учета использованных системных ресурсов отладочной кучи, объявляется в файле заголовка DBGINT.H.
typedef struct _CrtMemBlockHeader
{
// Pointer to the block allocated just before this one:
struct _CrtMemBlockHeader *pBlockHeaderNext;
// Pointer to the block allocated just after this one:
struct _CrtMemBlockHeader *pBlockHeaderPrev;
char *szFileName; // File name
int nLine; // Line number
size_t nDataSize; // Size of user block
int nBlockUse; // Type of block
long lRequest; // Allocation number
// Buffer just before (lower than) the user's memory:
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
/* In an actual memory block in the debug heap,
* this structure is followed by:
* unsigned char data[nDataSize];
* unsigned char anotherGap[nNoMansLandSize];
*/
Буферы NoMansLand с обеих сторон области пользовательских данных в блоке имеют размер 4 байта, и они заполняются фиксированным значением байта, используемым программами выделения памяти в куче, чтобы проверить, не были ли перезаписаны начало и конец пользовательского блока памяти. Новые блоки памяти отладочная куча тоже заполняет фиксированными значениями. Если хранить освобожденные блоки в связанном списке отладочной кучи (как объясняется ниже), эти блоки также будут заполняться фиксированным значением. В данный момент используются следующие действительные значения байтов:
NoMansLand (0xFD)
Буферы "NoMansLand" по обеим сторонам участка памяти, используемой приложением, заполняются значением 0xFD.Освобожденные блоки (0xDD)
Освобожденные блоки в связанном списке отладочной кучи хранятся как неиспользуемые блоки и, если флаг _CRTDBG_DELAY_FREE_MEM_DF установлен, они заполняются значением 0xDD.Новые объекты (0xCD)
Новые объекты при выделении памяти заполняются значением 0xCD.