I have a program question, here is the code.
int main()
{
int *p,*q;
p=(int*)1000;
printf("%d ",p);
q=(int*)2000;
printf("%d",q);
printf("%d",(p-q));
return 0;
}
But answer coming as
1000
2000
-250
I am unable to understand what happen with p-q and why answer came as -250?
Correct but probably useless answer: p - q is equal to (1000 - 2000) / (sizeof int). For most C compiles, sizeof int is 4.
Potentially more useful answer: the effect of typecasts like (int*) 1000 is undefined. That code creates a pointer to an int at address 1000. That address is probably invalid. To create a pointer to an int with value 1000, write this:
int i = 1000;
int *p = &i;
Now p points to i, and *p, the value pointed to by p, is 1000.
Here is some correct code that may say what you meant:
int main() {
int i = 1000;
int j = 2000;
int *p = &i;
int *q = &j;
printf("i = %d *p = %d\n", i, *p);
printf("j = %d *q = %d\n", j, *q);
printf("*p - *q = %d\n", *p - *q);
}
When you subtract two pointers, as long as they point into the same array, the result is the number of elements separating them.
On your platform, an int is 4 bytes. There are -250 elements between address 2000 and address 1000.
Since p and q don't both point to the same array, the result is undefined. You could get any result, including the one you expect.
So much undefined behaviour in this program, the values printed are really quite immaterial.
p is a pointer variable, which can store only address of a int variable. But you are storing 1000 as an address, which is invalid. And then you are storing 2000 to the variable q.
Now you are doing pointer arithmatic p-q. Always pointer arithmatic will gives the output based on the size of the type of address. Which will work like (p - q)/sizeof(type).
Consider if p and q are char * variable, then p-q will gives you the output as -1000
In your case p and q are int * variable, then p-q will gives you the output as 250 if size of int is 4 bytes. Execute this on the compiler where size of int is 2 bytes, you will get a result as -500.
Related
Using DevCpp with TDM GCC 4.9.2 on Windows 8. But I don't think the platform matters for this question.
I know that we can use a pointer to point to a single data or an array of data.
I have learned about pointer to arrays but never used it. What advantage does one have over the other?
Sample Code...
#include <stdio.h>
int main()
{
int x[2]={10,20};
int *p1= NULL; //simple pointer
int (*p2)[] = NULL; //pointer to an array, specifically
p1 = x;
p2 = &x; //removing the & gives me a warning of "assignment from incompatible pointer types".
printf("x[1] = %d\n", x[1]);
*(p1+1) = 7;
printf("x[1] = %d\n", x[1]);
(*p2)[1] = 55;
printf("x[1] = %d", x[1]);
return 0;
}
Does p1 or p2 have an advantage over the other?
They are completely different.
int *p; - is the pointer to the int
int (*p)[1]; is a pointer to the array (in this case one element only)
In your trivial example the pointer arithmetic will be the same and generated code will be the same. But they still have different types and you may get warnings when compiled.
The "advantages" you will see when your example will be less trivial:
int (*p)[100];
p++; the pointer will point to the next 100 elements int array.
Pointer to an array means a pointer which accepts address of an array.
let's say array is int arr[5],in which size of int is 4 byte.
p is a pointer to an array that accept the address of an int array.
int arr[5];
int (*p)[5];
p=&arr;//address of an array block
let's say the base address is 1000 .So after increment in p it will lead us to 1020 address,because the size of the array block is 20 bytes.
p points to 1000 address
p++;
//Now p points to 1020 not 1004.
Whereas in case of int *q, q will point to 1004 as usual.
CASE 1:
#include <stdio.h>
int main()
{
int arr[3] = {2,3,4};
char *p;
p = (char*) arr;
printf(" %p - %d\n",&p, *p);
p = p+1;
printf("%p - %d\n",&p, *p);
return 0;
}
output:
0x7ffde540b000 - 2
0x7ffde540b000 - 0
In above code value of pointer 'p' is increased by 1 - but address doesn't changed.
Again I increased the value of p by 4 (i.e p = p+4).
This time I get the following output -
0x7ffe50a2dff0 - 2
0x7ffe50a2dff0 - 3
pointer move to the location arr[1] and prints the correct value.
but address doesn't changed.
CASE 2:
Now rewritten the above code (removed '&' from print statement)
printf(" %p - %d\n", p, *p);
p = p+1;
printf(" %p - %d\n", p, *p);
output -
0x7ffdb20b9d1c - 2
0x7ffdb20b9d1d - 0
address changed by 1.
and similarly it works correctly when I update the code with p = p+4;
Output -
0x7ffef8735d6c - 2
0x7ffef8735d70 - 3
Address increased by 4.
I am not getting why address is not changed, when I am using '&' in print statement (CASE I).
What is difference between '&p' and 'p' in this case.
OS is Kubuntu and compiler GCC.
p is a variable of type char *
as a char * variable p holds values which represent pointers to characters.
&p is the address where this variable p is stored in memory.
When you write p = p + 1 you change the value of the variable p. But the variable p is the same variable, stored at the same memory, so naturally &p doesn't change.
the &-operator in c gives you the adress where the value is stored. so with &p you get the address where p is stored and NOT the adress of the value p points to. whichs is why the adress in your first case did not change.
case 2: you removed the & so you get the value of the adress where p points to which changes once you increase p.
i hope this is clear now :)
The problem is not what you are doing, but how you are printing the data.
int arr[3] = {2,3,4};
char *p = (char *) arr;
printf(" %p - %d\n", p, *p);
p = p+1;
printf("%p - %d\n", p, *p);
If you substitute the apparitions of &p by just p, then you'll get the results you expected. The problem is that & is read as "get the address of", so &p will return the address in which char * p is stored, ¡and that never changes!
int arr[3] = {2,3,4};
int *p = arr;
printf(" %p - %d\n", p, *p);
p = p+1;
printf("%p - %d\n", p, *p);
That's why your second block of code works. And just above these lines you have something which actually makes more sense, in which p is an int *.
I suggest you take a look at C-Sim (disclaimer: it was created by me), and follow the tutorials. C-Sim will draw a status diagram for code such as the one above.
Hope this helps.
int main(void)
{
int n1 = 2, n2 = 5;
int *p = &n1, *q = &n2;
*p = *(q++);
printf("%d,%d", *p, *q);
return 0;
}
output= 5,5
Why the value of *q is 5 it should have some garbage value?
int main(void)
{
int n1 = 2, n2 = 5;
int *p = &n1, *q = &n2;
*p = *(++q);
printf("%d,%d", *p, *q);
return 0;
}
output= 2,2
And how is this happening?
Can anyone explain how precedence rule works in pointers?
*p = *(q++); is (more or less) equivalent to *p = *q; q++;, so p is fine. q++ will be evaluated, yielding the old value of q (i.e. the value pre-increment). What you're seeing there is the expected behavior.
You do have undefined behavior in the deference of q in the printf call though since q no longer points at memory you own at that point. A million different things could be causing that (e.g. last time the memory was allocated, maybe a 5 was there, the compiler is being too nice and trying to help you, etc), but you cannot and should not depend on this behavior. Doing so is dangerous, and this program would likely crash or output nonsense on many compilers/operating systems/hardware.
Why the value of *q is 5 it should have some garbage value?
It is due to the postfix incrementation in *(q++) which acts after the pointer dereference and the assignment to *p.
So, the current value of the address pointed by *q is assigned to *p, and then q is incremented to a "garbage value".
This strange result in printing 5,5 is undefined behaviour.
If I run the following on OS X:
int main (void)
{
int* n; // initialise(declare) pointer
*n = 20; // the value in address pointed to by n is 20
printf("n: %i, n&: %i\n", n, &n);
return 0;
}
I get:
n: 1592302512, n&: 1592302480
Why the differing values?
Why do pointer and &pointer have different values?
The expression &n yields the address of n itself, while n evaluates to the value of the pointer, i.e. the address of the thing it points to.
But note that you have undefined behaviour First of all, because you are de-referencing an uninitialized pointer. You need to make n point somewhere you can write to.
For example,
int* n;
int i = 42;
n = &i;
// now you can de-reference n
*n = 20;
Second, you have the wrong printf specifier for &n. You need %p:
printf("n: %i, &n: %p\n", n, &n);
int* n declares a variable called n which is a pointer to an integer.
&n returns the address of the variable n, which would be a pointer to a pointer-to-integer.
Let's say we have the following code:
int a = 20; // declare an integer a whose value 20
int* n = &a; // declare a pointer n whose value is the address of a
int** p = &n; // declare a pointer p whose value is the address of n
In this case we would have the following:
variable name | value | address in memory
a | 20 | 1592302512
n | 1592302512 | 1592302480
p | 1592302480 | who knows?
In your code
int* n; //initialization is not done
*n = 20;
invokes undefined behavior. You're trying to de-reference (write into) uninitialized memory. You have to allocate memory to n before de-referencing.
Apart form that part,
n is of type int *
&n will be of type int **
So, they are different and supposed to have different values.
That said, you should use %p format specifier with printf() to print the pointers.
Just as an alternative, let me spell this out a different way.
char *ptr;
char c='A';
ptr = &c;
In this code, here's what's happening and what values are found when we qualify ptr in different ways.
ptr itself contains the address in memory where the char c variable is located.
*ptr dereferences the pointer, returning the actual value of the variable c. In this case, a capital A.
&ptr will give you the address of the memory location that ptr represents. In other words, if you needed to know where the pointer itself was located rather than what the address is of the thing that it points to, this is how you get it.
Can anyone explain the reason behind the second output? Also what is the difference between solving using int pointers and char pointers?
The second answer is coming out to be 0.
int main()
{
char arr[] = "geeksforgeeks";
char *ptr1 = arr;
char *ptr2 = ptr1 + 3;
printf ("ptr2 - ptr1 = %d\n", ptr2 - ptr1);
printf ("(int*)ptr2 - (int*) ptr1 = %d", (int*)ptr2 - (int*)ptr1);
getchar();
return 0;
}
Pointers of some type T point to objects of type T.
For example
int a[] = { 1, 2 };
int *p = a;
If you increase a pointer as for example
++p;
or
p = p + 1;
(take into account that these statements are equivalent) it will point to the next object of type T that follows the current object. So the value of the pointer will be increased by sizeof( T ) that to provide that the poiner indeed will point to the next element.
In the example above sizeof( int ) is (usually) equal to 4. So the value of the pointer will be increased by 4.
If you write
int a[] = { 1, 2 };
int *p = &a[0]; // the same as int *p = a;
int *q = &a[1];
then expression q - p will be equal 1 but the difference between the values stored in p and q will ve equal to sizeof( int ). p points to the first element of the array and q points to the second element of the array. It is so-called pointer arithmetic.
As for your result with subtracting int pointers then the behaviour is undefined. According to the C++ Standard
Unless both pointers point to elements of the same array object, or one
past the last element of the array object, the behavior is undefined
In your case int pointers do not point to elements of the same array. That they would point to the elements of the same array at least the difference of their values shall be equal to sizeof( int )
It's happen because char size is 1-byte, when int is 32Bit (4byte) variable
Edit keep pointer in the original array and ensure correct alignement to avoid undefined behaviour (see comment of Matt McNabb)
Because 3 < sizeof(int).
In pointer arithmetic, (int *) ptr2 - (int *) ptr1 gives real_addr_of_ptr2 - real_addr_of_ptr1) / sizeof(int) = 3 / 4. As it is integer division => 0 - this is not specified by C++ but is current implementation.
If you use : char *ptr2 = ptr1 + 8;, you will get : (int*)ptr2 - (int*) ptr1 = 2
As there are more than 8 characters in array, it can work, provided the original array is correctly aligned. To be coherent with the specs, it should have been declared :
union {
char arr[] = "geeksforgeeks";
int iarr[];
} uarr;
char *ptr1 = uarr.arr;