Some pointer clarification [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C question with pointers
I need some help with pointers, specifically the following example:
#include <stdio.h>
int main()
{
int *i, *j;
i = (int *) 60;
j = (int *) 40;
printf("%d", i - j);
return 0;
}
This code generates 10 as output. I just need to know what exactly i - j does here.

i and j point to memory locations 60 and 40, respectively.
What you're doing here is pointer subtraction. If i and j were byte pointers (char *), i-j would be 20, as one might expect.
However, with other pointers, it returns the number of elements between the two pointers. On most systems, (int *)60 - (int *)40 would be 5, as there is room for five 4-byte integers in those twenty bytes. Apparently, your platform has 16 bit integers.

The program is probably supposed to print the pointer difference between 60 and 40, cast to pointer to int. The pointer difference is the number of ints that would fit in the array from address 40 to address 60 (exclusive).
That said, the program violates the C standard. Pointer arithmetic is undefined except with pointers pointing into the same (static, automatic or malloc'd) array, and you cannot reliably print a pointer difference with %d (use %td instead).

This is pointer arithmetic, the code i - j subtracts two pointers to int. Such arithmetic is aware of the data sizes involved, and so in this case will return the number of ints between the two addresses.
A result of 10 indicates that you're running this on a system with 2-byte integers: 20 memory addresses between i and j, and your code prints 10, so there are 10 2-byte ints between the two addresses.
But on another system, with 4-byte integers, this would print 5: 20 memory addresses between i and j, so there are 5 4-byte ints between the two addresses.

printf("%d",i-j); return 0;
both i and j are pointer to an integer.So they follow pointer arithematics.
As per pointer mathematics pointer to an integer always shift sizeof(int).I
think you use gcc compiler where sizeof int is 4.So 60-40=20 but as unit is 4 so out put is
5.
but if you use turbo c where sizeof int is 2.then out put is 10.
NOTE
if pointers are included in some expression evaluation then they follow pointer arithematics.

i an j are the pointer to int variable, that means which is going to store virtual address of an int variable.
If we do any pointer arithmatic on this variable it will preform based on size of the type of variable which is pointing. For example i++ will increase the value from 60 to 64 if size of int is 4 bytes.
So you are getting 10 for i - j, that means size of int is 2 in your environment. Always i - j will give you how much element(of type int) that can accomodate in that range.
So between 60 and 40, we can store 10 elements of type int if size of int is 2 bytes.

First, two integer pointers are declared which are called i and j. Note that their values are memory addresses to where pointers are stored, not integers themselves (the concept of a pointer).
Next, the pointers i & j are changed to 60 and 40, respectively. Now this represents a spot in memory and not the integers sixty and forty because i and j was never dereferenced.
Then it prints the memory address of i-j which will subtract that two memory addresses.

Related

Unexpected result when doing subtraction of addresses of array elements

I am on a x32-based processor where char = 1 byte, short = 2 bytes and int = 4 bytes.
When I create an array of type char with 20 elements in it, I expect to see 20 memory spaces allocated to that array with the addresses differing by only 1 byte because of the type of the array.
If I take two consecutive elements from the array and subtract their addresses, should I then not get 1 in this case?
And in the case of arrays with types short and int, I am expecting to get 2 and 4. This due to the fact that the short and int elements need be aligned in memory. short elements will be on even addresses (diff 2) and int elements will be on addresses divisible by 4.
Though, how come when I run the following code I get 1,1,1 and not 1,2,4?
I suspect I am missing some cruical detail when it comes to pointer arithmetics.
char vecc[20];
printf("%i\n", &vecc[1]-&vecc[0]);
short vecs[20];
printf("%i\n", &vecs[1]-&vecs[0]);
int veci[20];
printf("%i\n", &veci[1]-&veci[0]);
Pointer subtraction yields the result as difference in the indexes, not the size of the gap between the addresses.
Quoting C11, chapter 6.5.6, (emphasis mine)
When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. [...]
If you write the code in this way:
printf("%i\n", (char*)(&vecs[1]) - (char*)(&vecs[0]));
printf("%i\n", (char*)(&veci[1]) - (char*)(&veci[0]));
the output will be 2 and 4.

What does the value on the subtraction of one double pointer from another double pointer signifies? [duplicate]

This question already has answers here:
Pointer subtraction confusion
(8 answers)
Closed 2 years ago.
int i = 9;
int *j = &i;
int* l = j + 1;
int **a=&j;
int **b=&l;
printf("%u\n",a);
printf("%u\n",b);
printf("%d\n",a-b);
Output:6422208
6422204
1.
What is 1 indicating to?
a contains the adress of the variable j (which contains itself the adress of variable i)
b is the adress of l.
Then the first two printf show you the adresses where variables j and l have been allocated to.
In your example j and l are contiguous in memory (I assume int is 32 bits on your architecture). It is just by luck, they could have been located far away from each other.
Finally, when you substract 2 pointers as in the last printf, you are doing arithmetic on pointers.
Incrementing a pointer adds to the adress the length of the type pointed to. For example if you print the values of variables j and l (not their adresses) you would find a difference of 4 between both adresses.
Similarly, the substraction of both adresses equals 4 which represent a difference of 1 in terms of pointer arithmetic for 32 bits architecture. That's why it prints the value 1.
However keep in mind that pointer arithmetic can be tricky. About substraction the C99 Standard states that:
When two pointers are subtracted, both shall point to elements of the
same array object, or one past the last element of the array object
So here I think you are allowed to substract a and b but this is not something you want to do in a real code.
Your code is unclean in many ways, see the comments. With that code doing experiments like the one you try to do will not give reliable results.
However lets assume that you have used appropriate code to output the difference of two addresses of pointers to int, of two variable int* j; int* l;.
&j is the address of the variable j, you can store it in a int** a;, same for int** b=&l;.
The value of the difference a-b now is only the difference of the addresses.
For that address difference, this line of your code is irrelevant. int* l = j + 1;, it only affects the value of what is pointed to by &l, i.e. not the address &l.
The value 1 cannot be explained reliably, because there is some freedom of implementation involved. But in many cases, this int *j; int *l; will result in j ending up immediatly "after" l in memory, i.e. at the next highest address. Because of pointer arithmetic this result in &j == (&l)+1. At this point the value of 1 for &j-&l is obvious.

Why do these two instructions vary in size?

Here are two instructions:
int p = 0;
int size_1 = (int*)(&p+1)-(int*)&p;
int size_2 = (char*)(&p+1)-(char*)&p;
I found that size_1 is 1 and size_2 is 4. I was wondering why they vary this way
This is basic pointer arithmetic. Oversimplifying a little bit, subtracting two int* produces the number of ints that fit between the two pointers (one), while subtracting two char* produces the number of chars that fit between the pointers (on your system, it happens to be four, because an int is four-byte wide).
The root cause is that an int is 4 bytes on your system, while a char is 1 byte. The code (&p+1) will return a pointer to the memory address 4 bytes (the sizeof(int)) after p. Then when you assign to size_1 you are asking for your answer in terms on int sizes, thus you get 1. For size_2, you are asking the difference between the address in char sizes, which gives 4.

issue in double pointer address addition

I have got one issue from a open source code in pointers side, which i have tried to replicate in this below small snippet.
int main()
{
int **a=0x0;
printf ("a = %d Add = %d\n", a, a+75);
return 1;
}
Expectation is to get 75/0x4B but this code gives 300 in 32 bit and 600 in 64 bit machines.
Output:
a = 0 Add = 600
But the ideology behind to access the added position i.e 75th position in Hash table.
So it should be
printf ("a = %d Add = %d\n", a, sizeof (a)+75);
But i couldn't able to guess why this 300 or 600 output. could anyone please point out?
I went till a point where there is some left shift internally happening since:
75 - 1001011
600 - 1001011000.
Solutions are appreciated. Thanks in advance.
Pointer arithmetic is always done using the size of what is pointed to. In your case a is a pointer to a pointer to int, so the unit size is sizeof(int*) which in your case seems to be 4 (32 bits). 4 * 75 = 300.
More precisely, a + 75 adds the byte offset sizeof(*a) * 75 (note the dereferencing of a) to the pointer. What happens is that you are effectively doing &a[75], i.e. you're getting a pointer to the 75:th element.
On a slightly related note, when you print pointers with printf you should be using the format "%p", and casting the pointers to void *. See e.g. this printf (and family) reference.
As for the different size on 32 and 64 bit systems, it's to be expected. A pointer on a 32-bit system is typically 32 bits, while on a 64-bit system its 64 bits.
The program behaviour is undefined:
The format specifier %d is not valid for pointer types: use %p instead.
Pointer arithmetic is only valid within and one past the last element for arrays, or one past the address of the scalar for scalars. You can't read a + 75.
First of all, use %p for printing pointers and %zu for a sizeof result.
That said, check the type of a, it is int **, which is the size of a pointer. And, it depends on the platform / compiler.
Pointer arithmetic honors the data type, so the initial pointer is always incremented based on the LHS data type.

Why address of i+2 is not 653064?

I'm learning pointers in C. I'm having confusion in Pointer arithmetic. Have a look at below program :
#include<stdio.h>
int main()
{
int a[] = 2,3,4,5,6;
int *i=a;
printf("value of i = %d\n", i); ( *just for the sake of simplicity I have use %d* )
printf("value of i+2 = %d\n", i+2);
return 0;
}
My question is if value of i is 653000 then why the value of i+2 is 653008 As far as I know every bit in memory has its address specified then according to this value of i+2 should be 653064 because 1 byte = 8 bit. Why pointer arithmetic is scaled with byte why not with bit?
THANKS in advance and sorry for my bad English!
As far as I know every bit in memory has its address specified
Wrong.
Why pointer arithmetic is scaled with byte why not with bit?
The byte is the minimal addressable unit of storage on a computer, not the bit. Addresses refer to bytes - you cannot create a pointer that points to a specific bit in memory1.
Addresses refer to *bytes*
|
|
v _______________
0x1000 |_|_|_|_|_|_|_|_| \
0x1001 |_|_|_|_|_|_|_|_| > Each row is one byte
0x1002 |_|_|_|_|_|_|_|_| /
\_______ _______/
v
Each column is one bit
As others have explained, this is basic pointer arithmetic in action. When you add n to a pointer *p, you're adding n elements, not n bytes. You're effectively adding n * sizeof(*p) bytes to the pointer's address.
1 - without using architecture-specific tricks like Bit-banding on ARM, as myaut pointed out
You should read about the pointer arithmetic.link given in the comment.
While incrementing the position of pointer , that will incremented based on the data type of that pointer.In this case i+2 will increment the byte into
eight bytes.
Integer is four bytes.(system defined). So i+2 will act as i+(2*sizeof(int)). So it will became i+8. So the answer is incremented by eight.
Addresses are calculating by the byte. Not the bit. Take a character pointer. Each byte having the 255 bits.
Consider the string like this. `"hi". It will stored like this.
h i
1001 1002
Ascii value of h is 104. It will be stored in one byte. signed character we can store positive in 0 to 127. So storing the one value we need the one byte in character dataype. Using the bits we cannot store the only value. so the pointer arithmetic is based on bytes.
When you do PTR + n then simple maths will be like
PTR + Sizeof(PTR)*n.
Here size of integer pointer is 4 Byte.

Resources