Почему это НЕ вызывает ошибки при разыменовании?unique_ptr - PullRequest
0 голосов
/ 02 июля 2019

Я ожидаю, что следующий код приведет к ошибке сегментации, прежде чем он попадет внутрь метода и напечатает что-нибудь. Почему не так? Почему же выполнение может войти в метод и напечатать вывод, например?

#include <memory>
#include <vector>
#include <iostream>

class Foo{
    public:
        void method(int x){
            std::cout << "wut" << std::endl;
            m_list.push_back(x);
        }
    private:
        std::vector<int> m_list;
};

int main()
{
    std::unique_ptr<Foo> example;
    example->method(0);
}

1 Ответ

0 голосов
/ 02 июля 2019

Это, конечно, неопределенное поведение, как указывали другие.

Однако во многих реализациях C ++ это действительно не произойдет до тех пор, пока после вывода не произойдет, потому что указатель NULL никогда не разыменовывается до этого момента.

Ваш main по существу сводится к reinterpret_cast<Foo *>(nullptr)->method(0). Поскольку method - это не virtual метод class Foo, который переводится в Foo::method(0)this, установленным в nullptr).

Выходная строка вообще не ссылается на this, поэтому только при обращении к m_list сначала разыменовывается this (и, следовательно, происходит сбой).

Если бы method было virtual, вызов к нему, скорее всего, прервался бы, как в типичных реализациях, вызовы virtual методов разыменовывают this.

...