简体   繁体   中英

Assigning an int value to a pointer in C

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.

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.

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...

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.

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM