Pointer Arithmetic In C - c

Consider the following code fragment:
int (*p)[3];
int (*q)[3];
q = p;
q++;
printf("%d, %d\n", q, p);
printf("%d\n", q-p);
I know that pointer arithmetic is intelligent, meaning that the operation q++ advances q enough bytes ahead to point to a next 3-integers-array, so it does not surprises me that the first print is '12, 0' which means that incrementing q made it larger in 12.
But the second print does surprises me. It prints 1!
So why would it print 1 instead of 12? it just puzzles me.

Like the ++ increment operator, the - subtraction operator with pointers also takes into account the size of the objects being pointed to. Specifically, the result returned is the number of bytes difference in the pointer values divided by the size of the pointed-to object (12, in your example). So the difference is 12 bytes, divided by size 12, or 1.

If you really want to know the difference cast each pointers to a (char*) and then to (int) and then subtract. That should give you the answer.
This code gives you the absolute value:
printf("%d\n", abs((int)((char*)q) - (int)((char*)p)));
Remember to include math.h.
Edit:
As pointed out in a comment we don't need a double cast. Casting each pointerpointer to an int and then subtracting gives the same answer as the (unecessary) double casting above.
printf("%d\n", abs((int)(q) - (int)(p)));

Related

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.

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.

Subtle differences in C pointer addresses

What is the difference between:
*((uint32_t*)(p) + 4);
*(uint32_t*)(p+4);
or is there even a difference in the value?
My intuition is that in the later example the value starts at the 4th index of the array that p is pointing at and takes the first 4 bytes starting from index 4. While in the first example it takes one byte every 4 indices. Is this intuition correct?
The p+4 expression computes the address by adding 4*sizeof(*p) bytes to the value of p. If the size of *p is the same as that of uint32_t, there is no difference between the results of these two expressions.
Given that
p is an int pointer
and assuming that int on your system is 32-bit, your two expressions produce the same result.

Some pointer clarification [duplicate]

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.

C array address confusion

Say we have the following code:
int main(){
int a[3]={1,2,3};
printf(" E: 0x%x\n", a);
printf(" &E[2]: 0x%x\n", &a[2]);
printf("&E[2]-E: 0x%x\n", &a[2] - a);
return 1;
}
When compiled and run the results are follows:
E: 0xbf8231f8
&E[2]: 0xbf823200
&E[2]-E: 0x2
I understand the result of &E[2] which is 8 plus the array's address, since indexed by 2 and of type int (4 bytes on my 32-bit system), but I can't figure out why the last line is 2 instead of 8?
In addition, what type of the last line should be - an integer or an integer pointer?
I wonder if it is the C type system (kinda casting) that make this quirk?
You have to remember what the expression a[2] really means. It is exactly equivalent to *(a+2). So much so, that it is perfectly legal to write 2[a] instead, with identical effect.
For that to work and make sense, pointer arithmetic takes into account the type of the thing pointed at. But that is taken care of behind the scenes. You get to simply use natural offsets into your arrays, and all the details just work out.
The same logic applies to pointer differences, which explains your result of 2.
Under the hood, in your example the index is multiplied by sizeof(int) to get a byte offset which is added to the base address of the array. You expose that detail in your two prints of the addresses.
When subtracting pointers of the same type the result is number of elements and not number of bytes. This is by design so that you can easily index arrays of any type. If you want number of bytes - cast the addresses to char*.
When you increment the pointer by 1 (p+1) then pointer would points to next valid address by adding ( p + sizeof(Type)) bytes to p. (if Type is int then p+sizeof(int))
Similar logic holds good for p-1 also ( of course subtract in this case).
If you just apply those principles here:
In simple terms:
a[2] can be represented as (a+2)
a[2]-a ==> (a+2) - (a) ==> 2
So, behind the scene,
a[2] - a[0]
==> {(a+ (2* sizeof(int)) ) - (a+0) } / sizeof(int)
==> 2 * sizeof(int) / sizeof(int) ==> 2
The line &E[2]-2 is doing pointer subtraction, not integer subtraction. Pointer subtraction (when both pointers point to data of the same type) returns the difference of the addresses in divided by the size of the type they point to. The return value is an int.
To answer your "update" question, once again pointer arithmetic (this time pointer addition) is being performed. It's done this way in C to make it easier to "index" a chunk of contiguous data pointed to by the pointer.
You may be interested in Pointer Arithmetic In C question and answers.
basically, + and - operators take element size into account when used on pointers.
When adding and subtracting pointers in C, you use the size of the data type rather than absolute addresses.
If you have an int pointer and add the number 2 to it, it will advance 2 * sizeof(int). In the same manner, if you subtract two int pointers, you will get the result in units of sizeof(int) rather than the difference of the absolute addresses.
(Having pointers using the size of the data type is quite convenient, so that you for example can simply use p++ instead of having to specify the size of the type every time: p+=sizeof(int).)
Re: "In addtion,what type of the last line should be?An integer,or a integer pointer??"
an integer/number. by the same token that the: Today - April 1 = number. not date
If you want to see the byte difference, you'll have to a type that is 1 byte in size, like this:
printf("&E[2]-E:\t0x%x\n",(char*)(&a[2])-(char*)(&a[0]))

Resources