При звонке DeviceIoControl
с IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
это заполняет VOLUME_DISK_EXTENTS
структура с указателями на некоторые данные (Extents
массив). Хотя структура, созданная в моем коде, освобождена от меня, массив указателей кажется тревожным.
Должен ли я освободить эту память?
Как мне это освободить?
Единственный задействованный указатель — это указатель на буфер, который вы передаете DeviceIoControl()
для этого, чтобы заполнить содержанием VOLUME_DISK_EXTENTS
структура. Там нет указателей внутри VOLUME_DISK_EXTENTS
, его Extents
member — это плоский массив структур, а не массив указателей. Эти структуры полностью содержатся в вашем выделенном буфере. Так что единственное, что нужно освободить — это ваш буфер, ничего больше.
На самом деле VOLUME_DISK_EXTENTS
определяется для хранения 1 предмета.
typedef struct _VOLUME_DISK_EXTENTS {
DWORD NumberOfDiskExtents;
DISK_EXTENT Extents[ANYSIZE_ARRAY]; // ANYSIZE_ARRAY == 1
} VOLUME_DISK_EXTENTS, *PVOLUME_DISK_EXTENTS;
Если мы позвоним DeviceIoControl
следующим образом
VOLUME_DISK_EXTENTS vde;
ret = DeviceIoControl(
h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL, 0, &vde, sizeof(vde), &bytesReturned, NULL
);
мы получим ERROR_MORE_DATA
код возврата, потому что в этой структуре недостаточно места. Extents
массив определяется размером 1 с тем фактом, что если вы попытаетесь получить доступ к элементам 1 и выше, вы попадете в пространство в буфере после VOLUME_DISK_EXTENTS
состав. Так что нам на самом деле нужно создать не VOLUME_DISK_EXTENTS
но буфер размера
sizeof(DISK_EXTENT) * (nextents - 1) + sizeof(VOLUME_DISK_EXTENTS)
где nextents
является VOLUME_DISK_EXTENTS::NumberOfDiskExtents
значение, которое мы получаем от предыдущего вызова. Тогда мы должны использовать
VOLUME_DISK_EXTENTS *ext = (VOLUME_DISK_EXTENTS*) buff;
и работать с этой структурой, предполагая, что Extents
массив имеет nextents
элементы.
Нет необходимости в дополнительных вызовах API для освобождения памяти. Все, что освобождается, является буфером.