Удалить и отлить. Удалит ли бесплатно нужное количество байтов? [дубликат]
Удалит ли бесплатно нужное количество байтов?
unique_ptr<sockaddr_in> up = make_unique<sockaddr_in>();
// or unique_ptr<sockaddr_in> up( new sockaddr_in ); ???
/*
Some stuff
sockaddr and sockaddr_in are two different types of struct and are not relateted
*/
sockaddr *p = reinterpret_cast<sockaddr *>( up.release() );
delete p;
2 ответа
В большинстве случаев,
sockaddr
не является базовым классом (источник 1, 2, 3):
struct sockaddr {
ushort sa_family;
char sa_data[14];
};
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
Следовательно, согласно [expr.delete] / p3 поведение программы не определено :
... если статический тип удаляемого объекта отличается от его динамического типа, статический тип должен быть базовым классом динамического типа удаляемого объекта, а статический тип должен иметь виртуальный деструктор или поведение не определено.
С учетом сказанного, во многих случаях встроенный оператор просто делегирует
free
, которому не нужен размер, и программа будет работать, как задумано (хотя при кодировании на C++ мы действительно предпочитаем оставаться в сфере определенного поведения).
Почему бы просто не позволить
unique_ptr
делать свою работу и
delete
в
sockaddr_in
при разрушении?
Он удалил бы
sizeof(sockaddr)
байтов, если только
sockaddr
это базовый тип
sockaddr_in
и получил виртуальный деструктор. Где бы это ни было, в противном случае это не определено. После того, как вы сделали
reinterpret_cast
,
sockaddr*
- статический тип указателя. вопрос в том, есть ли у него другой динамический тип или нет.