Удаленный выделенный элемент в куче оценивается как истина

struct Set
{
    int a;
    Set() : a(30){};
    bool operator>( const Set& ref ) const
    {
        return ref.a > this->a;
    };
};

int _tmain(int argc, _TCHAR* argv[])
{   
    vector<Set>m_set;
    m_set.push_back( (*(new Set)) );
    cout << m_set.at(0).a;
    delete &(m_set.at(0));
    if( &(m_set.at(0).a) )
        cout << "valid" << endl;

    return 0;
}

Почему он выводит valid, является ли удаление с использованием этого метода недопустимым?


person snoopy    schedule 30.10.2012    source источник
comment
См. Здесь: stackoverflow.com/questions/8839943/. (По сути, это неопределенное поведение, потому что вы удаляете не тот объект).   -  person R. Martinho Fernandes    schedule 30.10.2012
comment
если B object2 = *(new B()); удалить невозможно, почему это разрешено?   -  person snoopy    schedule 30.10.2012
comment
Зачем кому-то это делать? Мало смысла запрещать все действительно редкие бесполезные вещи, которые люди могут придумать. Никто не стал бы писать это, если не понимал базовых концепций C ++, таких как семантика значений.   -  person R. Martinho Fernandes    schedule 30.10.2012


Ответы (2)


При доступе к удаленному объекту поведение не определено. Все может случиться.

РЕДАКТИРОВАТЬ: и, что более важно, когда вы удаляете объект, который не был создан с помощью new, поведение не определено. Все может случиться. Вот что делает код здесь.

person Pete Becker    schedule 30.10.2012
comment
В этом случае UB происходит в операторе delete, потому что он удаляет копию выделенного объекта. - person Praetorian; 30.10.2012
comment
@Praetorian - спасибо; Я пропустил это. Объект, созданный с помощью new, копируется в вектор. Ответ отредактирован соответствующим образом. - person Pete Becker; 30.10.2012

У вас никогда не будет ссылки или указателя на объект, который вы разместили. Вектор создаст копию объекта, но вы полностью потеряли след самого исходного объекта, поэтому нет возможности восстановить или удалить его.

Вам необходимо выполнить одно из следующих действий:

T * p = new T;
delete p;

T & r = *new T;
delete &r;

Не используйте вторую версию.

person Kerrek SB    schedule 30.10.2012