0

I ran into a problem with an uninitialised unique ptr, here is the code:

class Demo {
   public:
    Demo() {}
    void noSegFault()
    {
        std::cout << "noSegFault" << std::endl;        
    }
    void segFault() {
        std::cout << "Address of data :" << &data << std::endl;
        std::cout << "Before segfault" << std::endl;
        data = 234;
        std::cout << "After segfault" << std::endl;
    }

   private:
    int data{123};
};

int main() {
    std::unique_ptr<Demo> demoPtr{nullptr};
    if (demoPtr == nullptr) {
        std::cout << "demoPtr is null" << std::endl;
    }
    demoPtr->noSegFault();
    demoPtr->segFault();
    return 0;
}

Output:

demoPtr is null
noSegFault
Address of data :0
Before segfault

In this context, demoPtr is initialized with nullptr. I used to believe that accessing nullptr would inevitably lead to a segmentation fault. However, in this program, I can successfully call the noSegFault method and observe its output. Yet, if I attempt to access any variables of the nullptr object(invoking segFault method), a segmentation fault occurs.

So as per the output I can able to invoke the methods which doesn't use its member variables successfully without segmentation fault.Is it the expected behaviour?

godblot link: https://godbolt.org/z/G34c1jefb

goodman
  • 424
  • 8
  • 24
  • 2
    There is no expected behavior. Accessing through a null pointer has undefined behavior – NathanOliver Feb 16 '23 at 15:39
  • @Jabberwocky, My expectation is the program should terminate when I try to use `demoPtr`, in the example it should not invoke `noSegFault` method. – goodman Feb 16 '23 at 15:41
  • I deleted my comment in the meantime, the [duplicate](https://stackoverflow.com/questions/1524312/why-am-i-able-to-make-a-function-call-using-an-invalid-class-pointer) explains it perfectly. – Jabberwocky Feb 16 '23 at 15:43
  • @goodman "Undefined behavior" means that there is nothing you can expect to happen or not happen. It is wrong that dereferencing a null pointer on the C++ language level will result in program termination or a null pointer exception or segmentation fault on the CPU level. Either is a valid outcome, but so is any other. – user17732522 Feb 16 '23 at 15:43
  • *"Undefined behavior means anything can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has UB. The program may just crash."* – Jason Feb 16 '23 at 15:46
  • @goodman you can try this `std::cout << "this = " << this;` in `noSegFault` and you'll mkost likely get an output likes this: `this = 0000000000000000`. – Jabberwocky Feb 16 '23 at 15:46
  • @Jabberwocky, thanks for the link, I will go through it. But is there any way to avoid this kind of pitfalls.I understand about undefined behavior but is there any way to terminate the program without invoking the `nosegfault` method? – goodman Feb 16 '23 at 15:47
  • @goodman Enable sanitizers `-fsanitize=undefined,address` in debug mode to catch these errors while testing. – user17732522 Feb 16 '23 at 15:54
  • @PeteBecker, ya fixed the typo, thank you. – goodman Feb 16 '23 at 16:06
  • `demoPtr->noSegFault();` crashes on my machine. *My expectation is the program should terminate when I try to use demoPtr...* **Undefined behavior** does not do that; you'd have to program that in yourself. Perhaps make a custom smart pointer that has that additional guarantee. – Eljay Feb 16 '23 at 16:08
  • @Eljay,Ya I will implement a wrapper for unique ptr for additional check. – goodman Feb 16 '23 at 16:39
  • Dereferencing a `nullptr` is [undefined behaviour](https://en.cppreference.com/w/cpp/language/ub) - a crash is one thing that can happen, but *anything* is allowed and you cannot count on any specific result. – Jesper Juhl Feb 16 '23 at 20:14

0 Answers0