0

Unable to figure out the dependency between the address of the specific variables, as appeared to the C complier, and the actual underlying hardware.

Consider example 1, after compiling of this code with cc t2.c, and executing it, it looks, it is not working as expected, the addresses of px and py are not getting interchanged for whatever reason.

Example 1:

#include <stdio.h>

void swap(int *,int *);

int main(){
    int x=3;
    int y=2;
    int *px;
    int *py;
    px=&x;
    py=&y;

    printf("px = %x\npy = %x\n",&px,&py);
    swap(px,py);
    printf("After the swap\npx = %x\npy = %x\n",&px,&py);
}

void swap(int *px,int *py){
    int temp;
    temp=*px;
    *px=*py;
    *py=temp;
}

gdb of example 1:

6                       int x=3;
(gdb) n
7                       int y=2;
(gdb) n
10                      px=&x;
(gdb) p x
$1 = 3
(gdb) p &x
$2 = (int *) 0x7efff5cc
(gdb) p px
$3 = (int *) 0x0
(gdb) p &px
$4 = (int **) 0x7efff5d4
(gdb) n
11                      py=&y;
(gdb) p px
$5 = (int *) 0x7efff5cc
(gdb) p &px
$6 = (int **) 0x7efff5d4

....

pi@readonly:~/new$ cc t2.c
pi@readonly:~/new$ a.out
px = 7ea765fc
py = 7ea765f8
After the swap
px = 7ea765fc
py = 7ea765f8

Example 2:

int x = 1, y = 2 ;int *ip;  /* ip is a pointer to an int */
ip = &x;  /* ip now points to x */
y = *ip;  /* y is now 1 */
*ip = 10; /* x is now 10 */
*ip = *ip + 1; /* x is now 11 */
*ip += 1; /* x is now 12 */
++*ip;   /* x is now 13 */
(*ip)++; /* x is now 14, parentheses are required */

Ex 1 Q:

1) Am I understand correctly, that, starting from the $5, px - is exactly the same variable as x, except it has its value set to 0x7efff5cc in hexadecimal, which is simply the address of the variable x in the memory??

2) If we use int *ip declaration, does it mean, that variable ip has the value equals to the address of int? Then, what is the address of int, in hexadecimal?

3) What does mean the address of the variable, what is this 0x7efff5cc? In other words:

  • I know, there are RAM, L2, L3, L1 caches of CPU, ROM. So, Address of which specific memory this number is representing?

  • How many such 0x7efff5cc can hold those specific type of memory? Or, where I can check it on Linux system?

4) What does (int **) notation mean?

5) What's wrong with the program, how to fix it, in order to get the addresses of px and py interchanged after being passed as an argument values to the function swap?

Ex 2 Q:

5) Regarding the notation, am I understand it correctly, that as soon as we declare that the variable ip is a pointer to int, via int *ip, we cannot assign, for example, the decimal value to ip, later on, using assignment like: ip = 10; since, after the variable has been declared as pointer, it is used solely for holding the addresses of other variables, to which ip "is pointing to", in hexadecimal?

readonly
  • 89
  • 7
  • 1
    The swap function is swapping the data values of the pointers not the pointers themselves. But the print function is printing the address stored in the pointers. If you want to swap the actual pointers then you need on more level of indirection, ie a point to a pointer. Print out the data stored in the values, it will be swapped. –  Feb 09 '19 at 16:01

2 Answers2

1

Ex 1 Q:

1) Am I understand correctly, that, starting from the $5, px - is exactly the same variable as x, except it has its value set to 0x7efff5cc in hexadecimal, which is simply the address of the variable x in the memory??

px is a pointer variable. That means px is a variable that contains an address. You assigned it to the address of x with px=&x, but you can assign any value to it.

2) If we use int *ip declaration, does it mean, that variable ip has the value equals to the address of int? Then, what is the address of int, in hexadecimal?

int *p is a pointer variable that points to an int. https://cdecl.org/?q=int+*ip%3B

3) What does mean the address of the variable, what is this 0x7efff5cc? In other words:

I know, there are RAM, L2, L3, L1 caches of CPU, ROM. So, Address of which specific memory this number is representing?

0x7efff5cc is a virtual address that the OS has given to the data space in your program to store the int x;

How many such 0x7efff5cc can hold those specific type of memory?

Linux can have many programs running at the same time that have the same virtual address but map to different physical addresses.

Or, where I can check it on Linux system?

see this for information on how to see what the physical address is for a virtual address on linux: Is there any API for determining the physical address from virtual address in Linux?

4) What does (int **) notation mean?

the variable is a pointer to a pointer to an int.

5) What's wrong with the program, how to fix it, in order to get the addresses of px and py interchanged after being passed as an argument values to the function swap?

fixed issues in your swap program:

#include <stdio.h>

void swap( int **, int ** );

int main()
    {
    int x = 3;
    int y = 2;
    int *px;
    int *py;
    px = &x;
    py = &y;

    printf( "px = %x\npy = %x\n", px, py );
    swap( &px, &py );
    printf( "After the swap\npx = %x\npy = %x\n", px, py );

    }

void swap( int **px, int **py )
    {
    int *temp;
    temp = *px;
    *px = *py;
    *py = temp;
    }

Ex 2 Q:

5) Regarding the notation, am I understand it correctly, that as soon as we declare that the variable ip is a pointer to int, via int *ip, we cannot assign, for example, the decimal value to ip, later on, using assignment like: ip = 10; since, after the variable has been declared as pointer, it is used solely for holding the addresses of other variables, to which ip "is pointing to", in hexadecimal?

no you can change what ip points to.

int *ip;
ip = &x; 
ip = &y;
ip++;
Bill Morgan
  • 538
  • 2
  • 14
  • Got you. I have noticed, that, in the fixed version of swap program, function `swap` is assigning the value of the variable `px` to the variable `py`, but, the virtual address of the variable `x` and variable `y` is remaining the same. Is it possible to swap the virtual addresses of variable `x` and variable `y`, itself, hence, manipulate the virtual addresses and not the values? – readonly Feb 10 '19 at 10:47
  • I don’t think so. If you had int x; then could move where x is located. a subsequent x=1 would write 1 to the old x location. – Bill Morgan Feb 10 '19 at 14:01
1

Your swap function is exchanging the values of x and y, not the values of px and py.

Since px == &x, that means *px == x, same is true for py.

For a function to write a new value to a parameter, you must pass a pointer to the parameter:

void foo( T *ptr )
{
  *ptr = new_value();  // write a new value to the thing ptr points to
}

void bar( void )
{
  T var; // for any non-array type T

  foo( &var ); // write a new value to var
  ...
}

This is true for any non-array type T, including pointer types. Let’s replace T with the pointer type P *, so the code is now

void foo( P **ptr )
{
  *ptr = new_value();  // write a new value to the thing ptr points to
}

void bar( void )
{
  P *var;

  foo( &var ); // write a new value to var
  ...
}

The semantics are exactly the same, all that’s changed is the type. If we want to write to a non-array object, we pass a pointer to that object. If we want to write to a pointer object, we pass a pointer to that pointer object.

So if you want you function to swap the values of px and py, it must be written as

void swap( int **ppx, int **ppy )
{
  int *tmp = *ppx; // int * = int *
  *ppx = *ppy;     // int * = int *
  *ppy = tmp;      // int * = int *
}

and called as

px = &x;
py = &y;
swap( &px, &py );
John Bode
  • 119,563
  • 19
  • 122
  • 198