I столкнулся с этим в стандартной библиотечной библиотеке GCC C ++ Pool_allocator.h, который содержит тип распределения, который использует пул памяти для повышения эффективности распределения небольших кусок памяти. В функции члена _m_refill () of __pool_alloc_base необходимо справиться с преобразованием типа из char* (который используется для управления необработанной памятью) до _obj* (который Является ли структура узла списка, используемая для управления бесплатной кусочкой). < /p>
Ситуация обречена следующей:
У меня есть указатель p < /code> to obj2 -тип, и я Необходимо преобразовать его в тип OBJ1, где OBJ1 и OBJ2 полностью не имеют никаких отношений наследования. Есть два способа достичь этого: < /p>
[*]
Код: Выделить всё
(obj1*)p
Код: Выделить всё
(obj1*)(void*)p< /code> < /li>
< /ul>
Мой вопрос:
Каковы различия между этими двумя? Зачем GCC выбрать второй путь? (Я думаю, что первый будет работать нормально как второй) Все то же, что и Reinterpret_cast (p)
Я думаю, это может быть связано с некоторыми проблемами платформы/компилятора, и выходит из проблем безопасности.
комплемент:
Вот функция члена _m_refill , которые получают параметр, который является размером блока свободного списка, который необходимо пополнить. Эта функция вызывается, когда свободный список блока определенного размера пуст. Сначала он использует _m_allocate_chunk , чтобы выделить большую часть необработанной памяти (как вы видите, тип возврата - char*), а затем создайте структуру свободного списка на необработанной памяти, используя __obj . < /p>
Код: Выделить всё
void* __pool_alloc_base::_M_refill(size_t __n) {
int __nobjs = 20;
char* __chunk = _M_allocate_chunk(__n, __nobjs);
_Obj* volatile* __free_list;
_Obj* __result;
_Obj* __current_obj;
_Obj* __next_obj;
if (__nobjs == 1)
return __chunk;
__free_list = _M_get_free_list(__n);
// Build free list in chunk.
__result = (_Obj*)(void*)__chunk;
*__free_list = __next_obj = (_Obj*)(void*)(__chunk + __n);
for (int __i = 1; ; __i++) {
__current_obj = __next_obj;
__next_obj = (_Obj*)(void*)((char*)__next_obj + __n);
if (__nobjs - 1 == __i) {
__current_obj->_M_free_list_link = 0;
break;
}
else
__current_obj->_M_free_list_link = __next_obj;
}
return __result;
}
Код: Выделить всё
union _Obj {
union _Obj* _M_free_list_link;
char _M_client_data[1];
};
Подробнее здесь: https://stackoverflow.com/questions/794 ... bj1p-where