1

In the following code:

int* p = (int*)0x2;
*p = 1;

This code leads to a Segmentation Fault. But:

int* p = (int*)0x2;
cout << (p == nullptr);

The output is 0. So:

  1. Is a pointer pointing to address 0x2 really a null pointer (Which causes a Segmentation Fault)?
  2. How can I handle cases like 0x2 by if statements? (I mean, handle cases in which dereferencing would cause a Segmentation Fault. Because as you see in if (p == nullptr) this case is not handled).
  3. What are addresses other than 0x2 which dereferencing a pointer pointing to them causes a Segmentation Fault and why?
Asesh
  • 3,186
  • 2
  • 21
  • 31
amirali
  • 1,888
  • 1
  • 11
  • 32
  • The value of null pointer `\0` is `00` – Asesh Apr 09 '20 at 11:19
  • segfault happens also with non nullptr pointers. Such as invalid pointers. or unaligned access. – Jarod42 Apr 09 '20 at 11:20
  • If you hover over your mouse the tag `segmentation-fault` you aldready got somekind of an answer: "Segmentation faults occur when accessing memory which does not belong to your process." – Eraklon Apr 09 '20 at 11:20
  • standard c++ doesn't provide way to know if pointer is valid/invalid. – Jarod42 Apr 09 '20 at 11:25
  • @Jarod42 So what do you do when you don't want to get a SegFault in dereferencing? (I sometimes assign NULL to pointers but they are somehow automatically assigned something like `0x2`) – amirali Apr 09 '20 at 11:29
  • 2
    A pointer being "automatically assigned 0x2" sounds like a bug you should fix. – Blastfurnace Apr 09 '20 at 11:34
  • Initialize your pointers to valid value, (including `nullptr`), test for `nullptr` before deferencing, Avoid reference/pointer dangling. Avoid raw owning pointers, use smart pointer or container instead. – Jarod42 Apr 09 '20 at 11:36
  • `struct Foo { short x; short y; }; Foo* p = nullptr; p->y = 100;` can result in dereferencing address 0x00000002. Depending on your platform, that may be a segmentation fault (or may be silently destructive, or may be perfectly fine). The segmentation fault is not part of C++, it's part of your platform. The undefined behavior is part of C++, and that only goes so far as to say "anything might happen". – Eljay Apr 09 '20 at 11:46
  • @Eljay Thanks, this is probably my problem. – amirali Apr 09 '20 at 12:02
  • Can you explain why you want to do this? Are you working with memory-mapped IO on an embedded system perhaps? Usually your development environment for that chip will provide compile-time constants (usually a #define) that provide the correct address instead of having to use a magic number. – JohnFilleau Apr 09 '20 at 13:52
  • 1
    @JohnFilleau I'm not interested in the number 0x2. That's because a bug (like what Elijay explained) caused some pointers point to that location and lead to segfault. – amirali Apr 09 '20 at 14:22

4 Answers4

5

The only integral value convertible to std::nullptr is 0.

Whether 0x2 is a valid memory address or not depends on your program. If you are simply aliasing this memory location as an int*, this is undefined behavior and you are lucky to get a segmentation fault.

The way you "handle" cases like 0x2 is to structure your program in some way so as to guarantee that 0x2 is a valid memory address. The address alone is often not sufficient. It's hard to guarantee no dangling pointers in a large codebase, but by using smart pointers and references intelligently, we can design a pretty safe program. Often you can get away with passing by value.

What are addresses other than 0x2 which dereferencing a pointer pointing to them causes a Segmentation Fault and why?

All of them. It depends on your program (and transitively your OS). You can't just interpret random memory locations as integers and then use them. Among other things, this will definitely violate the strict aliasing rule

AndyG
  • 39,700
  • 8
  • 109
  • 143
  • First paragraph is subtly wrong. All integral literals with value 0 are null pointer constants and therefore are convertible to `std::nullptr_t`. This includes 0L for example. Also, this was the case before C++11 already. Since C++11, `NULL` macro is no longer necessarily an integer literal, but is also allowed to be `nullptr`. – eerorika Apr 09 '20 at 11:44
  • +1 for "this is undefined behavior and you are lucky to get a segmentation fault." A seg fault is the BEST behavior to get in UB. Much easier to diagnose and fix than a silent error that quietly corrupts that one piece of data that's only accessed when you're in your safety-critical routine. – JohnFilleau Apr 09 '20 at 13:50
1

You can get segmentation faults on other addresses than null. It just means you're trying to access memory the operating system has reserved away from your program to use. For example, the early addresses are possibly for bootup processes and the like.

See also What is a segmentation fault?

Bondolin
  • 2,793
  • 7
  • 34
  • 62
1

Is a pointer pointing to address 0x2 really a null pointer (Which causes a Segmentation Fault)?

No, it's not a null pointer as the output 0 proved.

How can I handle cases like 0x2 by if statements? (I mean, handle cases in which dereferencing would cause a Segmentation Fault. Because as you see in if (p == nullptr) this case is not handled).

You can't. There is no list of all addresses that your program is allowed to use.

What are addresses other than 0x2 which dereferencing a pointer pointing to them causes a Segmentation Fault and why?

All addresses that are not assigned to your program by your operating system. Also writing to some addresses belonging to your program will cause undefined behavior like crashes.

Either you know special addresses like hardware or you allocate memory and get the corresponding address.

Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
1

Is a pointer pointing to address 0x2 really a null pointer

0x2 is not a null pointer constant.

The value of null however is unspecified. In theory, it could be 2. But on most systems it is 0. The output that you show demonstrates that null does not have the value 2 on your system.

(Which causes a Segmentation Fault)?

Indirecting through null is not the only thing that causes a segfault.

How can I handle cases like 0x2 by if statements? (I mean, handle cases in which dereferencing would cause a Segmentation Fault.

You "handle" them by never attempting to indirect through invalid pointers. There is no way to know whether a pointer is valid based on its value (except, we know that null is never valid).

What are addresses other than 0x2 which dereferencing a pointer pointing to them causes a Segmentation Fault and why?

From C++ perspective: Accessing any object outside of their lifetime causes the behaviour of the program to be undefined. If there is no object at address X, then accessing *X is undefined behaviour unless otherwise specified. Objects are created by defining variables, and using new-expressions.

From OS perspective, these things cause a segfault: All addresses, which are not mapped to any memory. All writes to read only memory.

eerorika
  • 232,697
  • 12
  • 197
  • 326