0
#include <stdio.h>
#include <conio.h>

void main()
{

  int m = 20;
  int n = 30;
  int *x = (int *)m;
  int *y = (int *)n;

  printf("%d", y-x);   //Output is 5
}

How is the output 5? One of the reason could be that x and y consider 20 and 30 as address and during pointer arithmetic the value could be (30-20)/(size of int) which is 10/2 = 5.

My doubt is what is the difference between returning pointer and returning address ? Why the address of m was not stored in pointer variable x?

Jeff Holt
  • 2,940
  • 3
  • 22
  • 29
Zephyr
  • 1,521
  • 3
  • 22
  • 42
  • The code is … problematic … at best, but basically invokes undefined behaviour for subtracting two pointers which don't point into the same array **and** using the wrong conversion type specifier for a `ptrdiff_t`. What do you expect? What are you trying to achieve? – too honest for this site Jul 14 '17 at 17:04

5 Answers5

4

The behaviour of your program is undefined.

Pointer arithmetic - including the difference between two pointers - is only valid within arrays (including one past the end of the arrray), or between the address of a scalar and one past that.

The behaviour of your casts from an int to a pointer to an int is also undefined.

If you do have a valid difference between two pointers, then use the format specifier %td to output it.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
3

The address of m wasn't stored in x because you didn't assign it the address of m. You assigned it the value of m. The cast you applied masked the fact that you attempted to assign an integer to a pointer, which the compiler would have warned you about.

If you want to use the address of a variable, use the address-of operator &:

int *x=&m;
int *y=&n;

You are correct regarding why the output is 5. The values of m and n are assigned to pointers and are thus treated as addresses.

Note however that pointer subtraction is undefined unless both operands point to members of the same array (or one past the end of that array). Also note that it is undefined behavior to print pointers with the %d format specifier. You need to use %p instead, and you need to cast the given parameter to void * (one of the rare cases where a cast to/from void * is required).

dbush
  • 205,898
  • 23
  • 218
  • 273
  • In case of linked list, we write node *p = (node *)malloc(sizeof(node)) . Here p points to the address of the memory location right? Then why not here ? – Zephyr Jul 14 '17 at 16:50
  • @Xylene23 The `malloc` function returns a pointer (a `void *` in particular), so the assignment is valid. Also, a `void *` can be freely assigned to or from any other object pointer so a cast is not needed in the case and in fact is discouraged. – dbush Jul 14 '17 at 16:52
  • So in case of malloc (void *) is a pointer which points to that memory location and it is assigned to p and in the above program pointer or address is not returned by the integer variable right? – Zephyr Jul 14 '17 at 16:56
  • @Xylene23 `malloc isn't a pointer, it's a *function*, specifically a function that *returns* a pointer, so it matches what it's being assigned to. In your above code, `m` is an `int` so that's the type of the expression, and that type does not match what is being assigned to. – dbush Jul 14 '17 at 17:04
  • @Xylene23 Correct. `malloc` returns an address, and that address is assigned to `p`. – dbush Jul 14 '17 at 17:06
  • The code above will still invoke UB for the subtraction and the printing. – too honest for this site Jul 14 '17 at 17:07
0

if you want to store the adress of m in x simply do int* x = &m; the casting to int type pointer here is causing the problem in my optinion. also if you want to calculate the values of y-x then do *y-*x. as it is in your code you calculate the adress of n - the adress of m.

c360
  • 67
  • 8
  • In case of linked list, we write node *p = (node *)malloc(sizeof(node)) . Here p points to the address of the memory location right? Then why not here ? – Zephyr Jul 14 '17 at 16:52
  • because malloc returns a void pointer, so the casting (node*) casts the void pointer into node pointer. so it's a pointer to pointer casting. what you did is casting the value to a pointer – c360 Jul 14 '17 at 16:58
  • @roy360; Casting `void *` is not necessary and can shadow other errors. It is strongly deprecated. – too honest for this site Jul 14 '17 at 17:10
  • @Olaf searching for more information about the subject led me to this post: https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc which was very enlightening. as mentioned in that post it is not completely useless to cast the pointer returned by malloc. but it looks like the disadvantages outweigh the advantages. thank you for pointing that out. – c360 Jul 14 '17 at 17:26
  • @roy360: An unnecessary cast is of absolutely no use! That's not only true for this specific cast, but any cast. It follows from what a cast is for and how it influences (silences) compiler diagnostics. – too honest for this site Jul 14 '17 at 17:42
-1

You have to use %p if you would like to show the address that is stored in a pointer. In your code, you should use * before the name of the pointer.

#include<stdio.h>

int main()
{

  int m=20; int n=30;

  int *x= &m;
  int *y= &n;

  printf("\n%d", (*y)-(*x));   //Output is 10
  printf("\n%p address of m", x); 
  printf("\n%p address of n", y); 
  return 0;
}
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Rafael Coelho
  • 166
  • 3
  • 10
-2
int *x=(int *)m;
int *y=(int *)n;

By doing this what you would be doing is -

in a pointer x - you put the value m ( Treat this as a pointer as well as you are doing int *.

Hence x would have a value of 20 ( 0x14 ) and y would have a value of 30 ( 0x1E).

Pointer arithmetic is bit different from normal arithmetic operation https://www.tutorialspoint.com/cprogramming/c_pointer_arithmetic.htm

And about assigning address you should use a &variable to do that