0

code snippet-1

int x=3;   
int *p=&x; 
printf("x= %d\n",x);
printf("p= %d\n",*p);

code snippet-2

int x;
int *p;
x=3;
*p=&x;
printf("x= %d\n",x);
printf("p= %d\n",*p);

Snippet-1 gives the output x=3 & p=3, but snippet-2 gives x=3 & p=Some random value

Please explain

Ayush Nanglia
  • 89
  • 1
  • 3
  • 10
  • 3
    In the second snippet, `*p=&x;` If that doesn't scream a warning, you need to raise your warnings to heightened levels, and treat them as errors because that's exactly what they are. Assigning `int*` to `int` is all kinds of wrong. – WhozCraig May 28 '20 at 11:47
  • @Lundin I don't know what you mean by "valid C", but snippet-1 compiles cleanly on a gcc compiler, giving the expected output. – Ayush Nanglia May 28 '20 at 12:17
  • 1
    @AyushNanglia Compiles cleanly means no warnings. Valid C means that it follows the actual C standard. gcc with default settings doesn't give errors for C language violations, only warnings. Read this: https://stackoverflow.com/questions/52186834/pointer-from-integer-integer-from-pointer-without-a-cast-issues – Lundin May 28 '20 at 12:29
  • To speak clearly, Lundin and Craig are right. `*p=&x;` is definitely wrong and not valid C as soon as `p` isn´t a pointer to pointer (which isn´t the case in your example). Reason why is explained in detail in the answers to your question. BTW they speak about snippet 2, not snippet 1. – RobertS supports Monica Cellio May 28 '20 at 12:57
  • I admit, *p=&x; is wrong and the compiler does give warning for that, but it executes **int *p=&x;** without any warning(s). That's all I wanted to clarify – Ayush Nanglia May 28 '20 at 15:13

4 Answers4

4

This line:

int *p=&x;

Is a declaration of p with initialization. It initializes p, which is an int *, to &x.

In contrast, this line:

*p=&x;

Is an assignment. It first dereferences p and then assigns &x to the dereferenced object. This is wrong for two reasons:

  • p doesn't point anywhere, so attempting to dereference it invokes undefined behavior.
  • Even if p did point somewhere, you would be trying to assign an int * to an int.
dbush
  • 205,898
  • 23
  • 218
  • 273
2

This code snippet has undefined behavior

int x;
int *p;
x=3;
*p=&x;
printf("x= %d\n",x);
printf("p= %d\n",*p);

because the pointer p was not initialized and has indeterminate value that does not point to a valid object. So this statement

*p=&x;

by dereferencing the pointer ( *p ) is trying to access the memory at an invalid address.

It seems that instead this statement

*p=&x;

you mean

p = &x;

that is the pointer gets the address of the variable x.

Pay attention to that the outputted message of such a call of printf

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

is confusing. It would be better to write

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

That is it is not the value of the pointer itself that is outputted but the value of the pointed object that is outputted.

You should distinguish the meaning of the asterisk in a declaration and in an expression.

In a declaration like this

int *p=&x; 

the asterisk means that here is declared a pointer and it gets the address of the variable x.

In an expression statement like this

*p=&x;

the asterisk denotes the dereferencing operator that is used to access the pointed object by means of the value stored in the pointer used as an address.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • the 'p' used in print was used just like any random variable in order to distinguish it from 'x', it doesn't really indicates to a pointer, though I got your point. – Ayush Nanglia May 28 '20 at 11:58
1

int *p=&x; is equivalent to

int *p;
p = &x; // <== p, not *p

p = &x takes the address of the variable x, and places it in p (which is a pointer).

Which is different than what you're doing in snippet-2

*p = &x; // Not the same

*p = &x takes the address of the variable x, and places it in the location pointed to by p. So, p is still pointing to the same location, but that location has a different value written to it. (and because p wasn't initialized, it is not pointing at anything useful, causing undefined behavior)

Aziz
  • 20,065
  • 8
  • 63
  • 69
1
int *p = &x;

(inside of the first snippet)

is different to

int *p;
*p = &x;

(inside of the second snippet)

In the first case you initialize p by the address of x.

In the second case, when using *p in the second statement, you dereference p which points to no valid object and attempt to assign the address of x to the non-existing object p shall pointing to, which invokes undefined behavior.

Normally this should give you at least a warning at compiling. Raise compiler warnings if it isn´t showed.

The * at the declaration is used to indicate the pointer.

The * after the declaration is used to dereference the pointer.


If you want snippet 2 to run properly, you need to omit the * at the assignment:

int x;
int *p;

x = 3;
p = &x;            // No * operator here.

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