1

These pieces of code cause a segmentation fault:

int *i;
printf("%d\n", *i);
int *i = NULL;
printf("%d\n", *i);

while these do not:

int *i;
i = malloc(sizeof *i);
int *i = NULL;
i = malloc(sizeof *i);

In all examples wild and null pointers dereferenced and passed as an argument to a function which should cause a segmentation fault. Why do the examples using malloc not behave as expected and produce a segmentation fault?

Equiphract
  • 107
  • 1
  • 11

3 Answers3

3

In the last two cases involving sizeof, the operand of the sizeof operator is not actually evaluated. It is observed for its type and the result is calculated at compile time.

Section 6.5.3.4p2 of the C standard regarding the sizeof operator states:

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

So there is no actual pointer dereference occurring.

Also, there's no guarantee that dereferencing a NULL pointer or an uninitialized pointer will cause a crash. It's actually undefined behavior, so it might crash, or it might not.

dbush
  • 205,898
  • 23
  • 218
  • 273
1

§ 6.5.3.4 The sizeof operator

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant

Shubham
  • 1,153
  • 8
  • 20
1
6.5.3.4 The sizeof and _Alignof operators
...
2     The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

C 2011 Online Draft

Under most circumstances sizeof does not evaluate its operand, so nothing gets dereferenced - it only cares about the type of the expression *i, not its value.

John Bode
  • 119,563
  • 19
  • 122
  • 198