I have a doubt in pointers manipulation...
main()
{ int x=10; // extra line added...
char *p=x;
printf("%d", &p)
printf("%d", &p[0]);
printf("%d" , &p[1]);
}
This code gives output
Address of 10..
10
11
how are the last two outputs are coming.. Can anyone explain it to me ..?
Code changed.....
This is Undefined Behavior.
The pointer needs to point to something valid before some value can be added to that location.
char a = 10;
char *p = &a;
Will explain two scenarios:
Scenario 1: char * p = x;
x == 10, p is a char pointer which is initialized with 10 (an address which user program can't access): p == 10
The value of p (ie, *p) will lead to segmentation fault (being invalid memory reference)
p[0] == *(p + 0) and &p[0] == (p+0) == p which is 10.
Hence printf("%p", &p[0]) will give you 10.
p[1] == *(p + 1) and &p[1] == (p+1)
Since, p is a character pointer, it gets increments by sizeof(char), ie 1
Hence printf("%p", &p[1]) will give you 10+1 = 11
Scenario 2: char * p = &x;
Here p is a char pointer pointing to integer x
Value of x = 10
Address of x = 1000 (assume)
Hence p = 1000
p[0] == *(p + 0) and &p[0] == (p+0) == p
Hence printf("%p", &p[0]) will give you 1000
p[1] == *(p + 1) and &p[1] == (p+1)
Since, p is a character pointer, it gets increments by sizeof(char), ie 1
ie &p[1] == 1000+1 == 1001
p and &p[0] will be evaluated to same address (address of first element of array) which is 10.
So &p[0] will be evaluated to 10 and &p[1] to &p[0] + sizeof(char) which is 11
Your code will most likely segfault though when you dereference p (*p).
Following code will always print True.
main()
{
int* p;
printf("%s\n",p == &p[0] ? "True" : "False");
}
Some errors in your code:
int x = 10;
char * p = &x; // error 1 - you was assigning int to pointer
printf("%p\n", &p); // error 2 - you printing address of pointer (char **),
// so different format string is needed
printf("%p\n", &p[0]); // same error 2 - printing address of first byte in int x
printf("%p\n" , &p[1]); // same error 2 - printing address of second byte in int x
printf("%d", &p[0]);
printf("%d" , &p[1]);
it will print out the address that p is pointered on..
because char *p=x; while x = 10;
then ,, &p[0] = 10, &p[1] = 11 &p[2] = 12 , and so on..
printf("%d", &p);
I'm not so sure about this, but as i know it will print out the value contained in memory 10 in my case = 10000
printf("%d", p);
it will print out the 10, which is the *p value;
cmiiw
char *p=10;
The code at present has undefined behavior. Pointer p is not pointing to any valid memory location to initialize 10 in that location.
With that said, both p, &p[0] yields the same memory location.
Related
Why on compiling the below piece of code is giving runtime error?
#include<stdio.h>
int main()
{
int i;
int *p;
int a = 10;
p= &a;
printf("address of a = %x\n",p);
*(p + 0) = 5;
*(p + 1) = 6;
*(p + 2) = 7;
*(p + 3) = 8;
for(i=0; i < 4; i++)
{
printf("address = %x value = %x\n",(p+i),*(p+i));
}
return 0;
}
In this code i am assigning values to the address of variable named a after that starting from address of a the values (6,7,8) respectively are getting assigned to the next address of a consecutively.
*(p + 1) = 6;
p is an int* - meaning that when you increment it by one, it doesn't jump one byte forwards - it jumps sizeof(int) bytes forward (probably 4 bytes). If you want to assign to the bytes separately, cast the pointer to a char*:
*((char*)p + 1) = 6;
When you write code like *(p + 1) = 6; - your program is very likely to crash. Per the standard this is undefined behavior, in practice what usually really happens behind the scenes is that since p == &a and a is on the stack, p + 1 points to 4 bytes in the stack above a - which likely contains some random value like a stack canary or a return address - and you are corrupting this value.
These expressions:
*(p + 1) = 6;
*(p + 2) = 7;
*(p + 3) = 8;
Create pointers that are past the memory bounds of a which are then subsequently dereferenced. Reading memory past the bounds of an object (or even attempting to create such a pointer if it is not just past the object) triggers undefined behavior.
In this particular case it caused your program to crash, but there is no guarantee that will happen.
You should allocate that memory before accessing it. Try using malloc().
Your code should look like this:
#include<stdio.h>
int main()
{
int i;
int a = 10;
char *p= (char *)&a;
printf("address of a = %p\n",p);
for (i = 0; i < sizeof(a); ++i) {
*(p + i) = i + 5;
}
for(i = 0; i < sizeof(a); ++i) {
printf("address = %p value = %d\n", p + i, *(p + i));
}
return 0;
}
One solution is to define p as a pointer to char. Another approach is, as suggested in other answers, just cast p into a pointer to char before any arithmetic. When using pointer arithmetic, the number of bytes you "jump" is as the size of the pointed type. So, p + 1 will jump 4 bytes, in case int is 4 bytes. This is why you should use a pointer to char if you want to move one byte at a time.
In addition, your loops should run N times, where N in the number of bytes. So, my suggestion is to use sizeof.
Last thing, please note that in order to print an int you should use %d, and use %p to print pointers (i.e addresses).
As you can see the output of the 6th and 7th print statement shows some random integer value, and I don't know why its happening!!!
6--> 4 5 4204752
7--> 4 5 4204753
#include <stdio.h>
int main()
{
static int a[] = {0, 1, 2, 3, 4};
static int* p[] = {a, a + 1, a + 2, a + 3, a + 4};
int** ptr;
ptr = p;
ptr++;
printf("1-->%d %d %d\n", ptr - p, *ptr - a, **ptr);
*ptr++;
printf("2-->%d %d %d\n", ptr - p, *ptr - a, **ptr);
*++ptr;
printf("3-->%d %d %d\n", ptr - p, *ptr - a, **ptr);
++*ptr;
printf("4-->%d %d %d\n", ptr - p, *ptr - a, **ptr);
**ptr++;
printf("5-->%d %d %d\n", ptr - p, *ptr - a, **ptr);
*++*ptr;
printf("6-->%d %d %d\n", ptr - p, *ptr - a, **ptr);
++**ptr;
printf("7-->%d %d %d\n", ptr - p, *ptr - a, **ptr);
}
At the beginning p points to p[0].
First three increments change p to point p[3]. Dereferences do nothing.
Fourth increment ++*ptr increments p[3] to a + 4.
Fifth increment changes p to p[4]. Again the dereferences do nothing.
Sixth increment first changes p[4] to a + 5. This is out of range for a, but as a special rule pointing to address past end of array is allowed. But then there is dereference, which tries to read a[5] and that results in undefined behaviour.
Seventh increment tries to increment a[5] by one, but this is again undefined behaviour.
So, to answer your question why last 2 print weird values, is because you read and write outside of array bounds. Program is broken and you get garbage results.
Initial condition:
ptr == &p[0] // int ** == int **
*ptr == p[0] == &a[0] // int * == int * == int *
**ptr == *p[0] == a[0] == 0 // int == int == int == int
After ptr++:
ptr == &p[1]
*ptr == p[1] == &a[1]
**ptr == *p[1] == a[1] == 1
After *ptr++ (parsed as *(ptr++), result of dereferencing ptr++ is discarded):
ptr == &p[2]
*ptr == p[2] == &a[2]
**ptr == *p[2] == a[2] == 2
After *++ptr (parsed as *(++ptr), result of dereferencing ++ptr is discarded):
ptr == &p[3]
*ptr == p[3] == &a[3]
**ptr == *p[3] == a[3] == 3
After ++*ptr (parsed as ++(*ptr), meaning you're not incrementing ptr but the thing ptr points to (p[3]):
ptr == &p[3]
*ptr == p[3] == &a[4]
^
|
+--- operand of ++
**ptr == *p[3] == a[4] == 4
After **ptr++ (which is parsed as *(*(ptr++)), results of the dereferences are discarded):
ptr == &p[4]
*ptr == p[4] == &a[4]
**ptr == *p[4] == a[4] == 4
After *++*ptr (which is parsed as *(++(*ptr)), so again you're not incrementing ptr but the thing ptr points to (p[4]) - result of the outer dereference is discarded):
ptr == &p[4]
*ptr == p[4] == &a[5]
^
|
+--- operand of ++
**ptr == *p[4] == a[5] == ???
Problem - p[4] initially points to a[4], which is the last element of a. Incrementing p[4] causes it to point to one element past the end of a.
Finally, ++**ptr (which is parsed as ++(*(*ptr)), so you're incrementing the thing that whatever ptr points to, points to; unfortunately, as shown above, **ptr evaluates to something outside the bounds of a)
ptr == &p[4]
*ptr == p[4] == &a[5]
**ptr == *p[r] == a[5] == ???
^
|
+--- operand of ++
Example code
int main() {
char *s = "kut";
char **p = &s;
printf("*s: %c\n", *s);
printf("s: %p\n", s);
printf("&s[0]: %p\n", &s[0]);
printf("p: %p\n", p);
printf("*p: %p\n", *p);
printf("**p: %c\n", **p);
printf("p[0]: %s\n", p[0]);
printf("&p[0]: %p\n", &p[0]);
return 0;
}
Output:
*s: k
s: 0x1043acf46
&s[0]: 0x1043acf46
p: 0x7ffeeb853670
*p: 0x1043acf46
**p: k
p[0]: kut
&p[0]: 0x7ffeeb853670
How does it come that &p[0] (address of p[0]) does print out the string kut? The output show that the address of p[0]is the same as p (as p is just a constant pointer pointing to the first element of the array).
For any pointer or array p and index i, the expression p[i] is exactly equal to *(p + i).
If i == 0 then we have p[0] which is equal to *(p + 0) which in turn is equal to *(p) which is the same as *p.
And in your case *p is the same as s.
Let's start with a diagram of how the variables all relate to each other:
char ** char * char
+---+ +---+ +---+---+---+---+
p: | |----> s: | |----> |'k'|'u'|'t'| 0 |
+---+ +---+ +---+---+---+---+
p stores the address of s, s stores the address of the first character in the string literal "kut", which is stored as an array of char somewhere in memory.
Given this, the following relationships are all true:
p == &s
*p == s == &"kut"[0] // believe it or not, this is legal - you
**p == *s == "kut"[0] == 'k' // can index into a string literal
Given that a[i] is defined as *(a + i), this also means that
*p == *(p + 0) == p[0] == s
and
&p[0] == &(*(p + 0)) == &(*p) == p;
and
*p[0] == *(*(p + 0)) == *(*p) == **p
How does it come that &p[0] (address of p[0]) does print out the
string kut?
For starters you are mistaken. This statement
printf("&p[0]: %p\n", &p[0]);
outputs the address of the pointer s
&p[0]: 0x7ffeeb853670
It seems you mean the output of this call
printf("p[0]: %s\n", p[0]);
that indeed shows on the console the string literal
p[0]: kut
The conversion specifier %s used in function printf expects a pointer to first character of a string.
For example this call of printf
printf("s: %p\n", s);
outputs the whole string literal "kut".
The pointer p is declared like
char **p = &s;
and points to the pointer s.
So dereferencing the pointer like p[0] or *p (that is the same) yields the value of the pointer s. That is p[0] is equal to s. So this call
printf("p[0]: %s\n", p[0]);
has the same effect as this call
printf("s: %p\n", s);
because seconds arguments of the calls have the same type and value.
Here is a demonstrative program.
#include <stdio.h>
int main(void)
{
char *s = "kut";
char **p = &s;
printf( "p[0] == s is %s\n", p[0] == s ? "true" : "false" );
return 0;
}
Its output is
p[0] == s is true
printf("%s", p[0]) means that you want to print a string that start at position p[0] or (*p) and will end when the \0 character is reached.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int k,*ptr=NULL;
int arr[]={1,2,3,4,5,6,7,8,9,10};
ptr=arr;
printf("%d ",*ptr++);
printf("%d ",*(ptr++));
printf("%d ",(*ptr)++);
printf("%d ",*++ptr);
printf("%d ",++*ptr);
}
Why does the second printf print the number 2 ? It should print 3.
As everyone else said, the distinction is between pre-incrementing (where the increment occurs before the value is fetched) and post-incrementing (where the value is fetched and then the increment occurs). The value 2 should be printed, of course.
Maybe this assertion-laden code will help. The assert() macro stops the program if the condition specified is false when it is executed. The assertions do not fire.
The assertions show how the value of ptr changes, and also how the values in the array change.
#include <assert.h>
#include <stdio.h>
int main(void)
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int *ptr = arr;
assert(ptr == &arr[0]);
printf("%d\n",*ptr++); // print 1; ptr = &arr[1]
assert(ptr == &arr[1]);
printf("%d\n",*(ptr++)); // print 2; ptr = &arr[2]
assert(ptr == &arr[2]);
assert(*ptr == 3);
printf("%d\n",(*ptr)++); // print 3; ptr = &arr[2]; arr[2] = 4
assert(ptr == &arr[2]);
assert(*ptr == 4);
printf("%d\n",*++ptr); // print 4; ptr = &arr[3]
assert(ptr == &arr[3]);
assert(*ptr == 4);
printf("%d\n",++*ptr); // print 5; ptr = &arr[3]; arr[3] = 5
assert(ptr == &arr[3]);
assert(*ptr == 5);
printf("Offset: %d\n", (int)(ptr - arr));
for (int i = 0; i < 9; i++)
printf("a[%d] = %d\n", i, arr[i]);
return 0;
}
Output:
1
2
3
4
5
Offset: 3
a[0] = 1
a[1] = 2
a[2] = 4
a[3] = 5
a[4] = 5
a[5] = 6
a[6] = 7
a[7] = 8
a[8] = 9
post increment operator increments the variabl after accessing the value.
So, after getting *ptr, which is 2, ptr increases itself.
Not, because ptr++ return the value BEFORE the incrementation, so the value is 2.
*ptr++ first dereferences the pointer which gives 2, then increments the pointer
The expression *(ptr++) is a post increment expression so the value of of that expression is ptr and then it is incremented. So the result of the expression is that it still points to the 2
the * operator applies to the result of p++, which is the value of original p (prior to the increment). So it prints 2. I you want 3 to be printed you should do (++p) which returns the incremented value.
It should print 2, because the postfix operator ++ first returns the value and then increments it.
The fact that you added brackets around it (*(ptr++)) does not influence the increment.
The value will be incremented after the whole line.
Looking at disassembly might help you to see what happens at that line.
The *ptr++ returns the value at ptr and then increments it,so in the second printf() statement it only returns 2 and then increments it to 3.
I have come across a code which goes like :
#include <stdio.h>
int main(void)
{
int a[5] = { 1, 2, 3, 4, 5};
int *ptr = (int*)(&a + 1);
int *ptr2 = (int*) &a;
ptr2 +=1 ;
printf("%d %d %d \n", *(a + 1),*(ptr - 1) ,*ptr2 );
return 0;
}
The pointer arithmetic does it for me except this line :
int *ptr = (int*)(&a + 1);
Is it undefined behaviour ?
Why do we get 5 on dereferencing *(ptr - 1) ?
The size of a is "5 ints". So &a + 1 refers to the first memory location past all of a, since the pointer arithmetic is done in units of the size of a.
Try it out!
int a[5] = {1, 2, 3, 4, 5};
printf("%#x, %#x, %#x, %#x\n", a, &a, a+1, &a+1);
0xbfa4038c, 0xbfa4038c, 0xbfa40390, 0xbfa403a0
So what does that tell us?
0xbfa4038c == 0xbfa4038c which means a == &a. This is the address of the first element in the array or a[0].
We know that the size of an int is 4, and you know that *(a+1) == a[1] (the second element in the array) and this is proven by:
0xbfa4038c + 0x4 = 0xbfa40390 which means a + one int = address of the next element
Thus if we see &a+1 == 0xbfa403a0, that means we're ((0xa0-0x8c)/4) = 5 elements into the array. You know that a[5] is invalid, so that means we're one passed the end of the array.
so if you take:
int *ptr = (int*)(&a + 1); //one passed last element in the array
printf("%d",*(ptr - 1));//back up one, or last element in the array and deference
That's why you get 5
For an array of n elements of type T, then the address of the first element has type ‘pointer to T’; the address of the whole array has type ‘pointer to array of n elements of type T’;
int *ptr = (int*)(&a + 1); //&a-> address whole array, size=20 bytes,
//ptr=&a+1: next element =adress of a +20 bytes.
//ptr - 1 = address of a +16 = address of last a's element = address of 5