1

Instead of initializing a pointer like this,

int main (){
    int *ptr;
    int x = 5;
    ptr = &x;
}

What happens in memory when you do something like this?

int main (){
    int *ptr = 100;
}

Would *ptr be looking for a random address that contains the value 100 or is it storing the value of 100 in ptr?

6 Answers6

3

This is a constraint violation, the compiler should give you a diagnostic message. (If the compiler doesn't say "error" then I would recommend changing compiler flags so that it does). If the compiler generates an executable anyway, then the behaviour of that executable is undefined.

In Standard C, this code does not assign 100 to the pointer, as claimed by several other comments/answers. Integers cannot be assigned to pointers (i.e. using the assignment operator or initialization syntax with integer on the right-hand side), except the special case of constant expression zero.

To attempt to point the pointer to address 100, the code would be int *ptr = (int *)100;.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • My copy of the standard begs to differ. 6.3.2.3 Pointers: "An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined [..]". – John Hammond Feb 14 '17 at 09:44
  • @LarsFriedrich In this case an explicit conversion operator is required. The conversions in that section are not all implicit conversions. Look up the assignment operator constraints – M.M Feb 14 '17 at 09:46
  • Maybe you should rephrase your "Integers cannot be assigned to pointers" part of the answer, as it is misleading the intent of your statement. – John Hammond Feb 14 '17 at 09:57
  • @LarsFriedrich In the line `int *ptr = 100;` there is nothing that causes a conversion, implicitly or explicitly. Therefore the rules of "simple assignment" applies - and assigning an integer to a pointer is not a valid form of simple assignment, hence the constraint violation. (If the assignment was valid, then there would be "lvalue conversion" to the type of the left operand.) Had you forced a conversion to take place, by for example adding an explicit cast, then the rules in 6.3.2.3 will kick in. – Lundin Feb 14 '17 at 10:22
2

First of all, as mentioned in other answers, the code int *ptr = 100; is not even valid C. Assigning an integer to a pointer is not a valid form of simple assignment (6.5.16.1) so the code is a so-called "constraint violation", meaning it is a C standard violation.

So your first concern needs to be why your compiler does not follow the standard. If you are using gcc, please note that it is unfortunately not configured to be a conforming compiler per default, you have to tell it to become one by passing -std=c11 -pedantic-errors.

Once that is sorted, you can fix the code to become valid C by converting the integer to a pointer type, through an explicit cast. int *ptr = (int*)100;

This means nothing else but store the address 100 inside a pointer variable. No attempts have been made to access that memory location.

If you would attempt to access that memory by for example *ptr = 0; then it is your job to ensure that 100 is an aligned address for the given system. If not, you invoke undefined behavior.

And that's as far as the C language is concerned. C doesn't know or care what is stored at address 100. It is outside the scope of the language. On some systems this could be a perfectly valid address, on other systems it could be nonsense.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Therefore, people telling you "uh dude you'll get a seg fault if you access address 100" probably assume that you are using a PC or some other system with virtual memory that blocks direct access of physical addresses. But no system was mentioned in the question, so such assumptions are not valid. – Lundin Feb 14 '17 at 10:54
  • The assignment itself can cause undefined behavior, there is no need to dereference the pointer. (Misaligned pointer will cause ub immediately. ) – 2501 Feb 14 '17 at 11:52
  • @2501 The standard is not all that clear. 6.3.2.3/5. "An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation." – Lundin Feb 14 '17 at 12:16
  • Two of those, alignment and trap, can cause ub immediately. What is unclear there? – 2501 Feb 14 '17 at 12:28
  • This is far and away the best and most complete answer here. – Colin Feb 14 '17 at 12:38
1
int *ptr = (int*)100; // valid
int *ptr = 100; // invalid as int to int * cast is not automatic

Usage of absolute address is discouraged because in a relocatable program segment, you would never know where a pointer should have as a value of some address, rather it should point to a valid address to avoid surprises.

Dr. Debasish Jana
  • 6,980
  • 4
  • 30
  • 69
0

Compiler won't give you any error. But it's a constraint violation. Pointer variables store addresses of other variables and *ptr is used to alter value stored at that address.

Rohit Mourya
  • 285
  • 5
  • 17
-1

The long and short of it is nothing. Assigning the value 100 to the pointer value p does something; it sets the address for the pointer value to 100, just like assigning the value of the call malloc to it would; but since the value is never used, it doesn't actually do anything. We can take a look at what the value produces:

/* file test.c */
#include <stdlib.h>
#include <stdio.h>

int main() {
  int *ptr = (int *) 100;
  printf("%p\n", ptr);
  return 0;
}

Executing this results in this output:

0x64

Pointers are, in a sense, just an integer. They (sometimes) take up about the same size of an integer (depending on the platform), and can be easily casted to and from an integer. There is even a specific (optional) type defined in C11 for an integer that is the same size as a pointer: intptr_t (see What is the use of intptr_t?).

Going back to the point, attempting to perform any dereferencing of this pointer of any kind can cause Weird Behavior(tm) - the layout of the memory is platform and implementation dependent, and so attempting to grab something at the address 100 will likely cause a Segmentation Fault (if you're lucky):

/* file test.c */
#include <stdlib.h>
#include <stdio.h>

int main() {
  int *ptr = (int *) 100;
  printf("%i\n", *ptr);
  return 0;
}

Executing results in this output:

fish: "./test" terminated by signal SIGSEGV (Address boundary error)

So don't do it unless you know exactly what you're doing, and why you're doing it.

Community
  • 1
  • 1
Jeremy Rodi
  • 2,485
  • 2
  • 21
  • 40
  • 1
    [don't put images of code or text output here](http://meta.stackoverflow.com/q/303812/995714). Copy and paste instead. Your answer will be invalid when external links rot – phuclv Feb 14 '17 at 10:09
  • @LưuVĩnhPhúc Images removed. – Jeremy Rodi Feb 14 '17 at 10:20
  • 1
    Your examples are not valid standard C. – Lundin Feb 14 '17 at 10:33
  • In older versions of C you didn't need a cast to assign an integer to a pointer, but you do now. If I compile your example with `gcc -std=c99` I only get a warning, but with `-std=c11` I get an error: Assignment makes pointer from integer without a cast. – Klas Lindbäck Feb 14 '17 at 12:23
-2

with:

int *ptr = 100;

you have assigned the value 100 to the pointer. Doing anything with it but printing its value will be undefined behavior:

printf ("pointer value is %p\n", (void *)ptr);
Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • 1
    What about in an embedded context where you know you have a register at address 100 you want to fiddle? – Colin Feb 14 '17 at 09:14
  • @Colin__s, In that specific context the behavior is defined by the platform. – Paul Ogilvie Feb 14 '17 at 09:15
  • Things you can do with it besides printing: re-assigning, subtracting, adding, ... – John Hammond Feb 14 '17 at 09:32
  • All `int *ptr = 100;` does is to trigger a compiler error. Make sure to use a standard compiler. If you add a cast `int *ptr = (int*)100;` it does _not_ lead to undefined behavior - that would be perfectly fine code as far as C is concerned. – Lundin Feb 14 '17 at 10:34
  • @Lundin, that is what I say (or intended to say). I intend to say that its _usage_ could lead to UB. – Paul Ogilvie Feb 14 '17 at 11:41