I want to get the address difference between two elements in an array.
int vector[] = { 28, 41, 7 };
printf("%d\n", &vector[2]); // 1703652
printf("%d\n", &vector[1]); // 1703648
printf("%d\n", &vector); // 1703644
printf("%d\n", &vector[1] - &vector); // 1
The result I expect(Last Line) is 4 because the data type was int.
Further, each result of address has 4 differences.
But why is the result of
&vector[1] - &vector
1 and not 4?
And how do I get 4 by using subtraction operator?
pointer arithmetics in C language works on the type of the object. It does not matter how big the object is. The reference to the next object minus reference to the previous is always one object
So if we add 5 to the pointer it will point 5 objects ahead. If we increment the pointer it will reference the next object. It helps indexing and iterating across the objects.
When you printf the address (your format is wrong - you should use %p instead) it is printed in bytes. So the difference between the consecutive objects will be equal the size of the object (plus the optional padding).
And How to I get 4 by using subtraction operator???
Cast the pointers to the type which sizeof is one for example char.
(char *)&vector[1] - (char *)&vector
You can calculate the difference of pointers to byte-sized values by casting the pointers to char *:
printf("%d\n", (char*)&vector[1] - (char*)vector);
Related
I have problem solving this problem, so if anyne had a similar problem it would help me a lot.
short y[2][3]={{0123},{0x12345}},*p=y[1];
printf("01:%x\n", y);
printf("02:%x\n", p);
printf("03:%x\n", sizeof(y));
printf("04:%x\n", sizeof(y[0]));
printf("05:%x\n", sizeof(&y[0]));
printf("06:%x\n", sizeof(*p));
printf("07:%x\n", sizeof(p++));
printf("08:%x\n", *p++);
printf("09:%x\n", *p);
return 0;
Can anyone explain to me why the printout is like this?
01:61ff10
02:61ff16
03:c
04:6
05:4
06:2
07:4
08:2345
09:0
My opinion:
01:Prints the address where the array y begins.
02:Prints the address of the pointer, which points to the second element of the array. Since we have 2 * 3 elements that are of type short, each subsequent element of the zero element will increase by 6.
03:Since we have 2 * 3 elements, which is equal to 6, but the elements of the type are short, so it will print hexadecimal c
04:the number of elements in the zero position is 3, but they are of the short type, so it prints 6
05:prints the sizeof addresses of the first element of the array which is 4
06:I don't know why it prints 2 here
07:Prints the sizeof of the pointer address which is 4, it will increase after printing
08:I do not understand
09:I do not understand
Can anyone explain why it prints like this?
OK, let's see:
#01: The address of y.
#02: The value of p, which holds the address of y[1], which is the second element of type short[3]. The size of a short is apparently 2 on your system, so the offset to #01 is 6.
#03: The size of the array y, 2 * 3 * sizeof (short) give 12, in hex c.
#04: The size of the element y[0], which is of type short[3]. 6, as you found.
#05: The size of the address of y[0], and apparently the size of an address is 4 on your system.
#06: The size of the object that p points to. This is a short, so 2.
#07: The size of the expression p++, which is an address, so 4. And no, p is not incremented, since the expression is not evaluated.
#08: The value of the object that p points to, which is y[1][0]. Since the initializing value of 0x12345 is an int too big to be stored in a short, it is truncated to 0x2345. After reading the value, p is incremented.
#09: The element p points to, which is y[1][1]. It was initialized to 0.
Notes:
You should have got warnings from your compiler:
The mentioned initializer is truncated.
The format for pointers/addresses is %p.
The type of the result of sizeof might not match the format %x.
You should take warnings seriously, they are always a hint that you most probably made an error.
N6) Sizeof(*p) is size of datatype pointed by p. p is pointer to short: so 2 bytes.
N8) p is pointer to short, it`s pointing to array element y[1][0].
y[1] and y[1][0] have the same memory address.
All array elements are short, 0x12345 truncates to 0x2345 upon array initialisation. So output is 2345.
Also, p++ increases pointer value to point to next short y[1][1].
N9) Because of p++ in step N8, pointer now points to y[1][1], which was initialised to 0 (by default, because init value not provided) - output is 0.
I was doing some practice with strings of different types and returning their address so I could understand the concept of pointer arithmetic better.
I noticed that when using the printf function, and %p as the reference character, the address would increment by 4 + 1 bytes when using the & operand on the variable, and by 1 byte without it.
Here is an example of my code and it's output:
1 #include <stdio.h>
2 #include <string.h>
3
4
5 int main ()
6 {
7 char charString_1[] = "Hello";
8 printf("%s\t%s\t %p\t %p\n", charString_1 + 1, charString_1 + 1, &charString_1 + 1, charString_1 + 1);
The output was the following
ello ello 0x7ffe76aba5d0 0x7ffe76aba5cb
Looking at the last two hex numbers only, the address is 203 and 208 (in decimal) respectively. So the latter is a char + int value bigger than the former. if I increment by two (&charString_1 + 2) , the gap is now 2(char + int) = 10 bytes.
I understand this question might be ridiculous, but my search results have turned up nothing. I'm trying to understand how memory works, and become better at finding common faults in buggy code.
When you do arithmetic on a pointer, the 'base unit size' is the size of the object pointed to.
So, for char_string, which points to a char (size = 1), the + 1 operation adds just one.
However, the expression &char_string evaluates as a pointer to an array, which (in your example) has a size of six characters (including the nul terminator), so the + 1 operation on that adds 6.
The difference in values printed by your two %p fields (5) is the difference between those two sizes (6 - 1 = 5). If you change the length of the array (e.g. like char charString_1[] = "Hello, World!";) you will see a corresponding change in the value of &charString_1 + 1.
"+1" will add the size of one of whatever type the compiler determines it is working with. In one case it believes it is working with a char, so it will add one byte (one "sizeof" a char). In the other case, it determines it is working with a pointer, so it will add one "sizeof" a pointer (typically 4 bytes).
(Edit: See below for the correction by Eric Postpischil, who points out that it actually sizeof pointer vs sizeof array)
I compiled this code and it gave the the value of '&x' 3 times. That is if &x = 2000 it printed 2036 three times. I want to know the reason for this behaviour assuming an integer requires 4 bytes of memory.
#include <stdio.h>
int main(void) {
// your code goes here
int x[4][3] = {0};
printf("%u %u %u", x+3, *(x+3), *(x+2)+3);
return 0;
}
What will be the output of this code
Anything can happen as the code provokes undefined behaviour by printing a pointer value using the conversion specifier for an unsigned.
To print pointer values use the conversion specifier p.
The address of an array and the address of its 1st element are the same. Pointers to them both however are of different type.
x as well as x + 3 are of type int (*)[3], that is pointing to an array of three ints. Assuming int to be of size 4, an array of three ints is of size 12.
Increasing x (a pointer to int (*)[3]) by three elements one ends up with an address 3 * 12 bytes beyond where x points to. This is called pointer arithmetic.
You're misusing a format specifier and invoking undefined behavior because of that. At that point, what happens is arbitrary and uninteresting.
If you want to print a pointer, use the %p specifier.
x is a pointer to an array of pointers. The array of pointers has 4 elements. Each of these four elements points to 3 integers.
Hence if x = 2000 then,
x[0] = 2000, x[1] = 2012, x[2] = 2024, x[3] = 2036.
Therefore,
x + 3 = 2036 (because x is an array pointer and it increases by 12 each time.)
*(x+3) = x[3] = 2036 again.
*(x+2)+3 = x[2] + 3 = 2024 + 3*4 = 2036 again.
Hence the output will be three same numbers.
Consider the following programm,
#include<stdio.h>
int main()
{
int marks[]={20,65,45,68,89};
int *x,*y;
x=&marks[2];
y=&marks[4];
printf("%p\n%p\n"x,y);
printf("%p\n%p\n",y-x,*y-*x);
return 0;
}
When I want to print out the value of y-x, the console should give me a output equal to the difference between the addresses of the corresponding pointers. After all, we know that x and y are having addresses ('some integer value'). However it is not so. Why?
Pointer subtraction does not simply subtract the addresses but rather return the distance between two array elements (in terms of arary elements).
So y - x is not a pointer but an integer of the value 2 - and to printf it, you shold use %d formatting, now %p.
If you print the differences using %p, you will probably get something that's a bit hard to read.
The proper way is probably to use %lu, and cast:
printf("%lu\n", (unsigned long) (y - x));
Printing the integer quantity *y - *x as %p seems totally confused.
The result of subtraction of 2 pointers in the same array is the distance between those pointers in array, so y-x should equal 2 in your example.
To get difference between addresses cast them to some integer before substracting:
printf("%d",(size_t)y-(size_t)x);
y-x will evaluate to 2 - since the distance in between them is 2 ints.
If you print e.g. (char *) y - (char *) x you will get the distance in characters
the console must give me a output equal to the difference between the addresses of the corresponding pointers
... and it does. For me, it outputs 2. If you compare the addresses, you see that they are separated by 8 bytes, which is 2 ints, which is the answer you sought.
I have an array as:
int x[3][5]={
{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15}
};
What does *x refer to?
*(*x+2)+5 refer to "8".How does that happen?
Is *(*x+2) same as *(*x)+2?
What if I do:
*n=&x;
Where is the pointer n pointing to? if it would have been only x and not an & then it would have been the base address.What for now?
*x is a dereference operation. In other words, "give me what x is pointing at". Since this is an array (of arrays), dereferencing x will give you the first array. This is equivalent to the array access syntax of x[0].
*(*x+2)+5 is equivalent to x[0][2] + 5, which gives you 8. This is because:
*x is the same as x[0] (see #1) and *(x + 2) is the same as x[2]. Once you've done two dereferences, you've gone from an array of arrays (similar to a double-pointer) to an array (single pointer) to an actual number (the third item in the first array). Then, it's just 3 + 5 = 8.
*(*x+2) is equivalent to x[0][2] (see #2), which is 3 (third element in array). However, *(*x) + 2 gives you x[0][0] + 2 (first element in array plus 2), which is 1 + 2 = 3. Same answer, but very different way of getting it.
*x refers to the first array ({1,2,3,4,5}), and is equivalent to x[0]. Adding one to x move to the next array, so *(x+1) would refer to the second array, and would be equivalent to x[1].
*(*x + 2) is therefore the third element in the first array, which is 3. This means that *(*x + 2) + 5 is equal to 8.
The parentheses matter a lot, for example *(*(x+2)) would be the first element in the third array.
*(*x + 2) results in the same value as *(*x) + 2, but does not use the same element of the array.
x is a int** so it's like if you have a first layer of pointers and everyone of them point to a int* (so an array of int).
When you write *x you obtain the address that contains the address which points to the first row of your multi dimensional array.
So if you take (*x + 2) if it's like referencing to first row of you array and then add 2 to the address: you obtain the address of the third element of first row. But since this is still a pointer you add an external *(*x+2) to exactly obtain third element of first row.
Think of it this way:
typedef int Int5[5];
Int5 x[3];
x is an array with 3 elements. Each of those three elements is a array of 5 ints.
What does *x refer to?
x is the same as '&x[0]so*xis the same asx[0]` which is the first 5-element array.
*(*x+2)+5 refer to "8". How does that happen?
*x is x[0], and x+2 is &x[2] so *x+2 is &x[0][2] and *(*x + 2) is x[0][2] which happens to be 3. Add five to that for 8.
Is *(*x+2) same as *(*x)+2?
*(*x+2) is x[0][2] as we've seen. *(*x) would be x[0][0], so *(*x)+2 is x[0][0]+2. So both *(*x+2) and *(*x)+2 end up equaling 3, but that is merely a coincidence.
All the answers are 100% correct and I will just generally explain this part *n=&x in general terms
&x generates a pointer (variable containing an address of another variable) and stores it in n and to get the value pointed to by n, you *n called de referencing or indirection.
To really understand this pointer business, you need to study how computers store values in memory.