#cpp #указатели
Собственно, ковыряю то, что написано в теме вопроса. Проблема возникла, когда я намеренно написал косячный код, а он, блин не упал. Собственно, код: #include#include struct cdmem { cdmem() { std::cout << this << " :: cdmem::cdmem()" << std::endl; }; cdmem(const cdmem&) { std::cout << this << " :: cdmem::cdmem(const cdmem&)" << std::endl; }; cdmem(const cdmem*) { std::cout << this << " :: cdmem::cdmem(const cdmem*)" << std::endl; }; void testf() { std::cout << this << " :: testf()" << std::endl; }; ~cdmem() { std::cout << this << " :: cdmem::~cdmem()" << std::endl; }; }; int main() { std::unique_ptr pd(new cdmem); if(!pd) { std::cout << "\n ERR1 " << std::endl; return 1; } pd->testf(); auto pd1(std::move(pd)); pd->testf(); // Вот тут указатель уже нулевой return 0; } Вывод: 0x801c06058 :: cdmem::cdmem() 0x801c06058 :: testf() 0x0 :: testf() // this равен 0x0 0x801c06058 :: cdmem::~cdmem() Получается, что обращения к самому объекту не происходит?
Ответы
Ответ 1
Это классическое UB, (обращение к более невалидному указателю), которое в данном случае выражается в нормальной работе. Это частный случай, который в другой ситуации (навскидку - виртуальный метод и вырубленная оптимизация) выстрелит вам в ногу. Не делайте так.Ответ 2
Тут играет роль неопределённое поведение. #includestruct A { void foo() { std::cout << "A::foo()\n"; } }; int main() { A * a = nullptr; a->foo(); } Вывод: A::foo() Это работает в MinGW 5.1.0, но далеко не факт что это будет работать в других версиях и в других компиляторах. Ответ 3
Классический случай UB. Если хотите чтобы 100% программа упала, попробуйте добавить в исследуемую структуру любое поле с данными (например int field = 12;) и обратиться к нему в вызываемой функции.Ответ 4
Вызов невиртуальной функции компилируется в обычный вызов функции с передачей параметром указателя this, в данном случае NULL. Если вы хотите настоящий UB - вызывайте виртуальную функцию.
Комментариев нет:
Отправить комментарий