11

I use this malloc style all the time

int *rc = 0;
rc = malloc(sizeof(*rc));

However, it doesn't seg fault even though when I call sizeof(*rc) I assume that rc==0, and I am dereferencing a NULL pointer.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
CallMeNorm
  • 2,299
  • 1
  • 16
  • 23
  • Possible duplicate of [Is sizeof(\*ptr) undefined behavior when pointing to invalid memory?](https://stackoverflow.com/questions/7721184/is-sizeofptr-undefined-behavior-when-pointing-to-invalid-memory) – Donald Duck Jul 31 '18 at 02:48

4 Answers4

26

You are not really dereferencing anything. The argument of sizeof is not evaluated, unless it is a VLA. It is explicitly allowed by the language to put whatever "garbage" you want as the argument of sizeof. The language guarantees that it will not evaluate anything, just perform compile-time analysis of the type of the expression. For example, expression sizeof i++ is guaranteed not to change the value of i.

The only exception from that rule is Variable Length Arrays. The result of sizeof for VLAs is a run-time value, which means that the argument is evaluated and must be valid.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Isn't it actually unspecified what, if anything, is evaluated in the VLA case? – R.. GitHub STOP HELPING ICE Nov 26 '12 at 23:36
  • 1
    @R..: C99 explicitly states that it is. For example, in case of VLA `int a[n][n]`, I would expect the expression `sizeof a[i++]` to increment `i`. I don't see using `sizeof` with side effects as a good programming practice, but nevertheless in such cases it is there. – AnT stands with Russia Nov 27 '12 at 00:52
  • Indeed, I was wrong about that. Nice clever example; in general, most expressions which could have side effects do not have VLA type (even though they may involve VLAs as operands). You pointed out one of the few examples where there's an expression with side effects whose type is a VLA type. – R.. GitHub STOP HELPING ICE Nov 27 '12 at 01:55
8

The sizeof operator doesn't actually evaluate its operand, it only looks at its type. The type of *rc is int, so it's equivalent to sizeof (int). This all happens at compile time.

(Also, this is not "inside of malloc".)

melpomene
  • 84,125
  • 8
  • 85
  • 148
4

You are not actually dereferencing a pointer, you are asking the compiler for the size of the type rc points to. In this case sizeof is resolved at compile time, when there are no pointers.

imreal
  • 10,178
  • 2
  • 32
  • 48
3

That's equivalent to sizeof(type of *rc) (in other words, sizeof(int)), not sizeof(data stored at the location pointed to by rc). sizeof() works on types, not values.

sizeof never considers the actual data, just the type, thus there's no need (and it wouldn't make sense) to deference the pointer.

Corbin
  • 33,060
  • 6
  • 68
  • 78