Это неопределенное поведение - никогда не пробуйте.
Давайте посмотрим, что произойдет, когда вы попытаетесь free()
автоматическая переменная. Диспетчер кучи должен будет определить, как стать владельцем блока памяти. Для этого ему придется либо использовать какую-то отдельную структуру, в которой перечислены все выделенные блоки и которая очень медленно используется редко, либо надеяться, что необходимые данные находятся в начале блока.
Последний используется довольно часто, и вот как я должен работать. Когда вы вызываете malloc (), менеджер кучи выделяет немного больший блок, сохраняет служебные данные в начале и возвращает указатель смещения. Что-то вроде:
void* malloc( size_t size )
{
void* block = tryAlloc( size + sizeof( size_t) );
if( block == 0 ) {
return 0;
}
// the following is for illustration, more service data is usually written
*((size_t*)block) = size;
return (size_t*)block + 1;
}
затем free()
попытается получить доступ к этим данным, смещая переданный указатель, но если указатель относится к автоматической переменной, все данные будут расположены там, где ожидается поиск служебных данных. Отсюда и неопределенное поведение. Много раз служебные данные изменяются с помощью free()
, чтобы менеджер кучи стал владельцем блока - поэтому, если переданный указатель относится к автоматической переменной, некоторая несвязанная память будет изменена и считана из.
Реализации могут отличаться, но вы никогда не должны делать никаких конкретных предположений. Вызывать free()
можно только по адресам, возвращаемым функциями семейства malloc()
.