2

According to this Berkeley course and this Stanford course, assigning an int to a pointer like so should crash my program:

#include<stdio.h>

int main() {

int *p;
*p = 5;

printf("p is %d\n", *p);

return 0;
}

Yet when I compile this on OSX 10.9.2 using GCC {Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)} I get the following output:

Chris at iMac in ~/Source
$ ./a.out 
p is 5

How come? I see the reverse question has been asked (Allocating a value to a pointer in c) but this only confuses me further as my program is nearly identical to the code posted in that question.

Community
  • 1
  • 1
Chris
  • 31
  • 5
  • 4
    you are de-referencing an uninitialized variable. Behavior is undefined. May not crash. Depends what the value of p is at the time. – OldProgrammer Feb 26 '14 at 19:26
  • 1
    To add to what OldProgrammer said, this is not guaranteed to crash your program, but it is undefined behavior. It's possible that p will point to space you've already been allocated, which will do what you see, or it could point to space you have not been allocated, in which case the program would throw a segmentation fault and quit. – IllusiveBrian Feb 26 '14 at 19:28
  • http://en.wikipedia.org/wiki/Undefined_behavior –  Feb 26 '14 at 19:29
  • And in addition to the above, just because it doesn't crash today, doesn't mean it won't crash tomorrow - whether or not the behaviour is even consistent is not guaranteed... – Corley Brigman Feb 26 '14 at 19:31
  • Your question title is mistaken. You are not allocating an "int" at all (that is the problem). Rather, you are allocating an int pointer, which is to say you are allocating a place to store a memory address (ie, a pointer), but not allocating or specifying any memory for the pointer to point to. – Chris Stratton Feb 26 '14 at 19:36
  • The value of p is uninitialized. So what memory address its pointing to is completely undefined, dependent on the compiler and program execution environment. Add something like printf("address of p is %X", (NSUInteger)p); This will show what the actual memory address that p is pointing to. If it was NULL, things would blow up. And if it's some random address that is writable, it'll work, maybe. :) – Travis Griggs Feb 26 '14 at 19:37
  • There's no guarantee that dereferencing even a NULL pointer will cause a failure, or that anything (or anything bad) will happen if you write there. Of course on most contemporary multiuser systems, this does trigger a protection fault. – Chris Stratton Feb 26 '14 at 19:39
  • @ChrisStratton correct, I meant assign not allocate. – Chris Feb 26 '14 at 19:42
  • The Stanford course seems to assume that `int *y;` is the same as `int *y = NULL;`. But there is no guarantee that unitialized variables will default to 0 (NULL) or any other address that is not part of the virtual address space of your process. – Asblarf Feb 26 '14 at 19:42

5 Answers5

2

You are not allocating int to a pointer. If p is a pointer, *p points to its value. You are assigning *p = 5; which is plain integer to integer assignment.

In this case, p is not initialized and may give rise to segmentation fault.

HelloWorld123456789
  • 5,299
  • 3
  • 23
  • 33
2

According to this Berkeley course and this Stanford course, allocating an int to a pointer like so should crash my program:

First off let's get your terminology correct. You are not "allocating an int to a pointer". Allocation is the creation of a storage location. An int is a value. A pointer is a value. A pointer may be dereferenced. The result of dereferencing a valid pointer is to produce a storage location. The result of dereferencing an invalid pointer is undefined, and can literally do anything. A value may be assigned to a storage location.

So you have:

int *p;

You have allocated a (short-lived) storage location called p. The value of that storage location is a pointer. Since you did not initialize it to a valid pointer, its value is either a valid pointer or an invalid pointer; which is it? That's up to your compiler to decide. It could always be invalid. It could always be valid. Or it could be left up to chance.

Then you have:

*p = 5;

You dereferenced a pointer to produce a storage location, then you stuck 5 in that storage location. If it was a valid pointer, congratulations, you stuck 5 into a valid storage location. If it was an invalid pointer then you've got undefined behaviour; again, anything could happen.

printf("p is %d\n", *p); // 5!

Apparantly you got lucky and it was a valid storage location this time.

According to this Berkeley course and this Stanford course [this] should crash my program:

Then those courses are wrong, or you are misquoting them or misunderstanding them. That program is permitted to do anything whatsoever. It is permitted to send an email inviting the president of Iran to your movie night, it is permitted to print anything whatsoever, it is permitted to crash. It is not required to do anything, because "permitted to do anything" and "required to do something" are opposites.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • *"If it was an invalid pointer then you've got undefined behaviour;" * - To be pedantic, it's undefined behavior either way. – Ed S. Feb 26 '14 at 19:47
1

My answers: You're lucky! The fact is, the value you happen to have in p is a valid memory address, that you can actually write to, this is why it works...

Try playing with optimising options (-O3) in your compiler, than you'll get different results...

Kissiel
  • 1,925
  • 1
  • 13
  • 11
  • And here is the wiki page about this luck - http://en.wikipedia.org/wiki/Undefined_behavior –  Feb 26 '14 at 19:29
  • I would say unlucky as he has a ticking time bomb on his hands instead of an obvious error. You also cannot assume that, because he did not receive a segfault, `p` points to a valid address. – Ed S. Feb 26 '14 at 19:33
  • Interesting. The lecturer at Berkeley explicitly states that the only instance of this pointer allocation that won't crash is if the value in the pointer's memory address points to itself. He also states that a pointer can only point to a specific type. Clearly both of these statements are false. – Chris Feb 26 '14 at 19:34
  • 1
    @Chris: He is wrong. It is undefined behavior. Undefined behavior doesn't mean "your program will crash." That would be defined behavior. – Ed S. Feb 26 '14 at 19:34
1

Your program is not guaranteed to fail, neither is it guaranteed to succeed. You are dereferencing a pointer which could hold any address. It is undefined behaviour.

wkz
  • 2,203
  • 1
  • 15
  • 21
0

It's not that it should crash, but it is undefined behavior.

Depending on the system and the runtime circumstances, assigning to a dereferenced and uninitialized pointer can either segfault or continue running "normally," which is to say that it appears work but may have unusual side effects.

yossarian
  • 1,537
  • 14
  • 21