Я думаю, что короткий ответ на это, что это не определено. В разделе 18.1.4 стандарта C ++ сказано:
Память для объекта исключения выделена неопределенным образом ...
MSVC, например, выделяет его в стеке . Удачи в этом.
Тем не менее, интересно выяснить, почему написанный код не работает (как и для других комментаторов, gcc сообщает о повреждении памяти, когда я пытаюсь его запустить), и, как говорит @AlanBirtles, ответ лежит здесь:
https://code.woboq.org/gcc/libstdc++-v3/libsupc++/eh_alloc.cc.html
Если вы посмотрите на реализацию __cxa_allocate_exception
(строка 279), вы увидите, что она делает три вещи, которые вы не делаете:
- выделяет дополнительное пространство для заголовка (частного) типа
__cxa_refcounted_exception
- обнуляет этот заголовок
- возвращает указатель на первый байт после этого заголовка
Затем в __cxa_free_exception
он разрешает настройку указателя перед его освобождением.
Так что достаточно легко заставить его работать, просто сделайте что-то вроде этого (или, может быть, вы можете проложить свой путь к объявлению __cxa_refcounted_exception
, я думаю, что это где-то на этом сайте):
#define EXTRA 1024
extern "C" void * __cxa_allocate_exception(size_t thrown_size)
{
void *mem = malloc (thrown_size + EXTRA);
std::cout << "allocate: " << mem << " (" << thrown_size << ") " << std::endl;
memset (mem, 0, EXTRA);
return (char *) mem + EXTRA;
}
extern "C" void __cxa_free_exception(void *thrown_object)
{
std::cout << "free: " << thrown_object << std::endl;
char *mem = (char *) thrown_object;
mem -= EXTRA;
free (mem);
}
И когда я запускаю это в Wandbox , я получаю:
allocate: 0x1e4c990 (1)
MyException constructed.
allocate: 0x1e4ddb0 (1)
MyException constructed.
MyException destroyed.
free: 0x1e4e1b0
MyException destroyed.
free: 0x1e4cd90
-----------
allocate: 0x1e4c990 (1)
MyException constructed.
allocate: 0x1e4ddb0 (1)
MyException constructed.
MyException destroyed.
free: 0x1e4e1b0
MyException destroyed.
free: 0x1e4cd90
-----------
allocate: 0x1e4c990 (1)
MyException constructed.
allocate: 0x1e4ddb0 (1)
MyException constructed.
MyException destroyed.
free: 0x1e4e1b0
MyException destroyed.
free: 0x1e4cd90
-----------
Этот не работает с clang , поэтому они должны делать вещи по-другому. Как я уже сказал, это UB, так что будьте осторожны.