Я нашел некоторые места в заголовках Visual Studio, где память освобождается через указатель на void.
файл xlocnum:
template<class _Elem>
class numpunct
: public locale::facet
{
_PROTECTED:
_VIRTUAL __CLR_OR_THIS_CALL ~numpunct()
{ // destroy the object
_Tidy();
}
...
protected:
void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj)
{ // initialize from _Lobj
_Grouping = 0;
_Falsename = 0;
_Truename = 0;
_TRY_BEGIN
_Grouping = _MAKLOCSTR(char, _Ptr->grouping, _Lobj._Getcvt());
_Falsename = _MAKLOCSTR(_Elem, _Lobj._Getfalse(), _Lobj._Getcvt());
_Truename = _MAKLOCSTR(_Elem, _Lobj._Gettrue(), _Lobj._Getcvt());
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
...
}
...
private:
void __CLR_OR_THIS_CALL _Tidy()
{ // free all storage
_DELETE_CRT_VEC((void *)_Grouping);
_DELETE_CRT_VEC((void *)_Falsename);
_DELETE_CRT_VEC((void *)_Truename);
}
...
const char *_Grouping; // grouping string, "" for "C" locale
const _Elem *_Falsename;// name for false, "false" for "C" locale
const _Elem *_Truename; // name for true, "true" for "C" locale
};
или другой пример в xlocale:
template<> class _CRTIMP2_PURE ctype<char>
: public ctype_base
{
public:
explicit __CLR_OR_THIS_CALL ctype(const mask *_Table = 0,
bool _Deletetable = false,
size_t _Refs = 0)
: ctype_base(_Refs)
{ // construct with specified table and delete flag for table
...
if (_Table != 0)
{ // replace existing char to mask table
_Tidy();
_Ctype._Table = _Table;
_Ctype._Delfl = _Deletetable ? -1 : 0;
}
}
protected:
void __CLR_OR_THIS_CALL _Tidy()
{ // free any allocated storage
if (0 < _Ctype._Delfl)
free((void *)_Ctype._Table);
else if (_Ctype._Delfl < 0)
delete[] (void *)_Ctype._Table;
}
}
Как было отмечено на https://stackoverflow.com/a/941959/1549256 удаление через указатель void не определено стандартом C ++.
Почему в таких случаях правильно освобождать память?
Код в реализации стандартной библиотеки не должен соответствовать определению языка. Это может воспользоваться знанием реализации; вот почему он поставляется с компилятором.
Неопределенный не означает, что это не будет работать, это просто означает, что реализация свободна делать все, что захочет, в том числе работает хорошо.
Одной из возможных проблем с удалением указателя приведения является то, что деструктор не может быть вызван, но это не может быть проблемой, если тип не имеет конструктора, который необходимо изменить при удалении.