I have an error message:
cannot increment value of type int[2]
Is that because the size of int or what?
int arr[2]={10,20};
printf("%p \t %p \t",arr,++arr);
The only reason you are not able to modify its value is once you define a static array with n size then a variable name given to it is treated as constant pointer (Whose value can't be changed).
This restriction is imposed by the compiler because it thinks if you change the value arr then there no way to ensure the accuracy of the program because the base address has been modified
But if you really want to play with the pointers then check these codes:
int main() {
int arr[] = {1,2,3,0};
int *ptr = arr;
while(*ptr != 0) {
printf("%i ",*ptr);
ptr++; // or ++ptr;
}
return 0;
}
Output: 1 2 3
int main() {
int *arr = (int*)malloc(4*sizeof(int));
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 0;
while(*arr != 0) {
printf("%i ",*arr);
arr++;
}
return 0;
}
Output: 1 2 3
I hope i made myself clear. Any doubt most welcome.
Please note that you are trying to modify address of array.
Consider:
printf("%p \t %p \t",arr,++arr);
I think you want to print the address of the array element at 2nd position(index 1).
To print the address if arr[1] you can try:
&a[1]
(a+1)
use pointers
use dynamically allocated arrays
#define ARRAY_COUNT 10
int main() {
int *arr = (int*)malloc(ARRAY_COUNT*sizeof(int));
while(*arr != 0) {
printf("%p ",arr);
arr++;
}
return 0;
}
Final Code:
#include <stdio.h>
int main()
{
int arr[2]={10,20};
int *ptr=arr;
printf("%p \t %p \t\n",ptr,ptr+1);
printf("%p \t %p \t\n",arr,arr+1);
printf("%p \t %p \t\n",arr,&arr[1]);
return 0;
}
Sample Output:
sh-4.3$ gcc -o main *.c
sh-4.3$ main
0x7fffdf064110 0x7fffdf064114
0x7fffdf064110 0x7fffdf064114
0x7fffdf064110 0x7fffdf064114
Also note that the statement:
printf("%p \t %p \t",arr,++arr);
is an Unspecified or Implementation-specific behavior since it can (and does) produce different results on different machines. To be concise, the order(left to right or otherwise) of passing the arguments to functions is not strictly specified by C.
Here:
printf("%p \t %p \t",arr,++arr);
Case 1: Left to right parameter passing causes arr address(address of a[0]) to be printed first and then incremented to print the next address(address of a[1])
Output:
0x7fffdf064110 0x7fffdf064114
0x7fffdf064110 0x7fffdf064114
0x7fffdf064110 0x7fffdf064114
Case 2: Right to left parameter passing causes arr address to be incremented first and printed (address of a[1]) and then print the address(address of a[1])
Output:
0x7fffdf064114 0x7fffdf064114
0x7fffdf064114 0x7fffdf064114
0x7fffdf064114 0x7fffdf064114
Related
I'm a beginner in C language.
I'm practicing several codes on my own, while doing I came across this algo.
Below is the code.
#include <stdio.h>
int main() {
int a = 1;
printf("value of a = %d\n", a);
printf("address of a = %u\n", &a);
int *p;
printf("value of p = %d\n", p);
p = 2;
printf("value of p = %d\n", p);
a = a+p;
printf("value of addition =%d\n", a);
return 0;
}
**OUTPUT**
value of a = 1
address of a = 947268620
value of p = 947268880
value of p = 2
value of addition =6
Why I'm getting 6 instead of 3,
is there anything I'm missing on result
because you're not setting the value of the address p is pointing to to 2, you're assigning/pointing the variable int *p to the value 2 in memory, which is not memory you should be accessing. Instead, you need to point p to memory you have access to (a variable or dynamically allocated memory) and dereference the pointer using *p = 2 which accesses the value that p is pointing to. Your code should instead look like this
int a = 1;
printf("value of a = %d\n", a);
printf("address of a = %u\n", &a);
int _p = 0;
int *p = &_p;
printf("value of p = %d\n", *p);
*p = 2;
printf("value of p = %d\n", *p);
a = a+*p;
printf("value of addition =%d\n", a);
One has to "walk right past" the compiler warnings about that code.
Below is the same code with coercive casting to silence some of the warnings. An additional calculation and print statement should make obvious how the compiler deals differently with the values of pointers (memory addresses) and the values of integers.
#include <stdio.h>
int main() {
int a = 1;
printf("value of a = %d\n", a);
printf("address of a = %u\n", &a); // incorrect format spec for printing address
int *p;
printf("value of p = %d\n", p); // uninitialised and undefined behaviour
p = (int*)2; // coercive casting integer to pointer-to-integer
printf("value of p = %d\n", p); // incorrect format spec for a memory address
a = (int)(a + p); // coercive casting address to integer
printf("value of addition =%d\n", a);
// ADDED these statements
a = 1; // restore value of a
a = a + (int)p; // coercive casting address to integer
printf("value of addition =%d\n", a);
return 0;
}
value of a = 1
address of a = 1703728
value of p = 1
value of p = 2
value of addition =6
value of addition =3 <== was this the expected result?
C will try to do its best with explicit program statements.
"Garbage in, garbage out."
Write correct code, not 'cute' code.
Thanks for your response Awayy. Helpful.
I got the output I needed. But the thing I need to know is, in what logic
the line a = a+p; gave 6 as result in my code.
As u said I'm assigning 2 as address to p(which is p = 0x2).
So, when the addition happens a = 1 and p = 0x2 which has a random value that we don't know that is because I'm not assigning a particular address to the pointer variable p. It results 6 I'm I right.
I have the following code. I tried to change the value of y by using a pointer to a pointer (i.e. trying to do a de-referencing twice from the pointer that points to another pointer). this is my code, but for some reasons it doesn't work, could someone tells me where I have done wrong:
#include <stdio.h>
void changeAddr(int **j) {
(*j)++;
printf("change pointer's address to: %p\n", j);
(**j)++; // is there something wrong with this part? I want to increase the
// value pointed to by the pointer pointed to by j (so I thought
// it would be the value of y in main, but there is an error message
// the error says: *** stack smashing detected ***: terminated
printf("change the value pointed to by the pointer by using a pointer: %0d\n", **j); // this does not
// give value 7 for some reasons
}
void inval(int *i) {
(*i)++;
printf("address of i: %p\n", i);
printf("just increased: %0d \n", *i);
changeAddr(&i);
}
int main()
{
printf("Hello World\n");
int y = 5;
inval(&y);
//printf("%0d\n", y);
printf("%p\n", &y);
printf("value of y in the end: %d\n", y);
return 0;
}
int y = 5;
inval(&y);
/* inside intval(int *i): i points to a single int */
(*i)++; // Increments y
changeAddr(&i);
/* inside changeaddr(int **j): j points to a pointer to a single int */
(*j)++; // Increments i; i now points to the next thing after y;
// the spec says we can always do this but dereferencing it is undefined
(**j)++; // Increments the next thing after y; oops that's undefined behavior */
When I try to print this
#include <stdio.h>
int main(){
int x = 3;
int *ptr = &x;
//printf("Address is : %d\n",&ptr);
ptr++;
*ptr = 1;
printf("%d %d",x,ptr);
return 0;
}
The code outputs 3 1, shouldn't it be 3 (then address of ptr?). Then, when I uncomment first printf it prints out:
Address is : 6356744
3 6356752
Does anyone know what is going on?
You have several serious problems in your code.
1) You print a pointer value or an address of a variable using %d but should not. That is undefined behavior so we can't know what will happen. To print a pointer value or an address of a variable use %p and cast to a void pointer like:
printf("Address is : %p\n",(void*)&ptr);
2) You write to memory that is not allocated to your program. These lines:
ptr++;
*ptr = 1;
make you write the value "1" one step past x. So this is also undefined behavior.
Correction the above could give you this program:
#include <stdio.h>
int main(){
int x = 3;
int *ptr = &x;
printf("Address is : %p\n",(void*)&ptr);
ptr++;
// *ptr = 1;
printf("%d %p\n",x,(void*)ptr);
return 0;
}
With the possible output:
Address is : 0x7ffc5b0923c8
3 0x7ffc5b0923c8
but the output may change from run-to-run and system-to-system
I have a question about pointers. I am beginning to grasp the concept, but this particular piece of code is threatening that understanding, and I just want to clear it up.
Please note line "B", which is printf("ptr + %d = %d\n",i, *ptr++); /*<--- B*/
I was under the impression that, since *ptr was initialized to &my_array[0], then *ptr++ (which would translate to "whatever is at the address stored in ptr, add one to it") would print out 23, which is the value at my_array[1].
Yet, it prints out the value at my_array[0], which is 1.
I'm confused as to whether the ++ adds to the address itself (like, 1004 becomes 1005) and, since the integer takes up about 4 bytes of space, it would fall into the range of my_array[0] (because that value, 1, would take up addresses 1001, 1002, 1003, 1004, and since my_array[0] starts out at 1001 and only goes up to 1002, then *ptr++ would still print out my_array[0], which is 1)...
or...
Whether *ptr++ goes from my_array[0] (which is just *ptr) to my_array[1] *ptr++, which is what I originally thought.
Basically, please explain what *ptr++ does to this program in particular. Please explain it to me as though I was a five year old.
I really appreciate it, and here's the code:
#include <stdio.h>
int my_array[] = { 1, 23, 17, 4, -5, 100 };
int *ptr;
int main(void)
{
int i;
ptr = &my_array[0]; /* point our pointer to the first
element of the array */
printf("\n\n");
for (i = 0; i < 6; i++)
{
printf("my_array[%d] = %d ", i, my_array[i]); /*<-- A */
printf("ptr + %d = %d\n", i, *ptr++); /*<--- B*/
}
return 0;
}
Change this:
printf("ptr + %d = %d\n",i, *ptr++); /*<--- B*/
to this:
printf("ptr + %d = %d\n",i, *(++ptr)); /*<--- B*/
When you use the postfix version if the increment operator, the value of the object before the increment is returned by value by the expression. The prefix increment operator (which the second set of code in this answer uses) will return the incremented object by reference.
*ptr++ will increment after the printf. You should use *(++p).
#include<stdio.h>
#include<stdlib.h>
int main ()
{
int a[]={0,1,2,3,4};
int *p[]={a,a+1,a+2,a+3,a+4};
int **ptr=p;
ptr++;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
*ptr++;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
*++ptr;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
++*ptr;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
return 0;
}
The answer for this program is
1 1 1
2 2 2
3 3 3
3 4 4
with gcc.But why is the output for the first printf giving 1 1 1 shouldn't it be 4 4 1?
lets say if p=6004 and and ptr would be 6004 and ptr++ would be 6008.then ptr-p should give 4.pls correct me.thanks..
The result of pointer arithmetic is not exactly the result of their address arithmetic. The output should be ((address of ptr) - (address of p)) / (sizeof(pointed_type))
For example:
int a[] = {0,1,2,3,4};
int *p=a;
int *p2 = p+1;
printf("%d",p2-p) // will print 1
I modified it a little to be certain. The point here is that subtracting pointer returns the number of units i.e. address / size of pointer, not plain difference of address locations.
printf("ptr before %p\n", ptr);
ptr++;
printf("ptr after %p and p %p\n", ptr, p);
printf("%ld %ld %d\n",ptr-p,*ptr-a,**ptr);
On my 64 bit machine, the printed addresses are 8 locations apart with just a single ++. On a 32 bit machine this would be 4. But still the arithmetic difference would return 1.