Same C pointer showing different values? - c

I'm running this program:
#include<stdio.h>
void main(){
int num = 1025;
int *poinTer = &num;
char *pointChar = poinTer+1;
*pointChar = 'A';
printf("Size of Integer: %d\n", sizeof(int));
printf("Address: %d, Value: %d\n", poinTer, *poinTer);
printf("Address: %d, Value: %c\n", poinTer+1, *(poinTer+1));
printf("Address: %d, Value: %c\n", pointChar, *pointChar);
}
*pointChar and *(poinTer+1) should output same result but the output that I'm getting is different. *pointChar is not outputting any value:
Size of Integer: 4
Address: 1704004844, Value: 1025
Address: 1704004848, Value: A
Address: 1704004673, Value:
What's happening here?

When you perform + 1 on a pointer, it does not necessarily increase the memory address by 1. It increases it by sizeof(*ptr).
In this case, poinTer + 1 is equivalent to (char*)poinTer + sizeof(int). This actually makes dealing with arrays much easier.
The good old fashioned ptr[i] is syntactic sugar for *(ptr + i). So, if you have an array of 10 integers, ptr[4] will point to the 5th element rather than 4 bytes away from the base address (since integers are generally 4 or 8 bytes).
So what you've actually done is:
Create an int (num) on the stack and gave it the value 1025
Created a int*(poinTer) on the stack and assigned it the memory address of num
Incremented the pointer by sizeof(int) (which unintentionally points to a different memory address), then cast it to a char* and assigned it to a new pointer.
Assigned the byte pointed to at this new memory address the value 65 ('A').
This is probably what you wanted to do:
#include<stdio.h>
void main(){
int num = 1025;
int *poinTer = &num;
char *pointChar = (char*)poinTer + 1;
*pointChar = 'A';
printf("Size of Integer: %d\n", sizeof(int));
printf("Address: %d, Value: %d\n", poinTer, *poinTer);
printf("Address: %d, Value: %c\n", (char*)poinTer + 1, *((char*)poinTer+1));
printf("Address: %d, Value: %c\n", pointChar, *pointChar);
}

Related

add local variable and pointer variable

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.

How to double deref in C?

Trying to double dereference and print them (TOP TWO ARE EXAMPLES):
printf ("a's value = %d \n", a) ;
printf ("a's address = %p \n", &a) ;
printf ("a_ptr_ptr deref'ed defer'ed =d% \n",
What would go after the \n", for a_ptr_ptr deref'ed defer'ed
If you want the address of the address of a, you're going to have to store a's address in a pointer variable, and take the address of that. But having done so, yes, you can double-dereference that pointer with **, and get a's value back. Something like this:
int a = 5;
int *ip = &a;
int **ipp = &ip;
printf("ipp = %p\n", ipp);
printf("*ipp = %p, ip = %p, &a = %p\n", *ipp, ip, &a);
printf("**ipp = %d, *ip = %d\n", **ipp, *ip);
Theoretically you can continue this as long as you like:
int ***ippp = &ipp;
int ****ipppp = &ippp;
int *****ippppp = &ipppp;
printf("*****ippppp = %d\n", *****ippppp);
But by now this is mostly a game; there's no practical use in a real C program for a 5-level pointer, and at some point (after 8 or 10 levels, I think) the compiler's allowed to say "All right, enough, game over!".

C program stopped working when i tried changing some address values

Have a look at my code :
#include <stdio.h>
#include <limits.h>
int main (int argc, const char *argv[]) {
typedef unsigned char byte;
byte *pointer;
byte b1=1;
byte b2=2;
int i1 =4;
int i2 =0x12345678;
byte b3=5;
byte b4=6;
byte b5=7;
byte b6=9;
//pointer = &b6;
pointer = (byte*)&i2;
printf("pointer has value %p\n", pointer);
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
*pointer = 255;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
*pointer = 45;
printf("the byte it points to contains %x\n", *pointer);
pointer = pointer + 1;
*pointer = 34;
printf("the byte it points to contains %x\n", *pointer);
//printf("How big is int in this machine? %d\n", INT_MAX);
//insert code here ...
printf (" b1 (%p) = %x\n", &b1, b1);
printf (" b2 (%p) = %x\n", &b2, b2);
printf (" i1 (%p) = %d\n", &i1, i1);
printf (" i2 (%p) = %x\n", &i2, i2);
printf (" b3 (%p) = %x\n", &b3, b3);
printf (" b4 (%p) = %x\n", &b4, b4);
printf (" b5 (%p) = %x\n", &b5, b5);
printf (" b6 (%p) = %x\n", &b6, b6);
return 0;
}
The line saying *pointer = 255; , maybe 40th line , the compiler blows , or the code stops working , saying this
if I make , *pointer = 255 or *pointer = 254
and if I set any other values except this , my program works well i.e.
*pointer = 4556 or *pointer = 45
Or in case of any other arbitrary values as well , it runs without any blow . Please tell me about this behaviour of addresses.
Source : Prof. Richard Buckland , I'm exploring all these due to his guidance.
The compiler has nothing to do with this. You're trying to dereference and assign to an invalid pointer, to memory you do not own.
Doing just ++pointer; *pointer = <value>; is dangerous as pointer points to a single value of type int, so ++pointer (or adding any number except zero to it) is moving the pointer to some memory location you probably don't have permission to write to or even access. Hence the errors.

address space of variables changing in c program

The address space of an variables seems to be varying in my program. First I got the following output from the program below.
int main(){
int a = 10;
int *b = &a;
int **c = &b;
int ***d = &c;
printf("a - address: %p, value: %x\n",&a ,a );
printf("b - address: %p, value: %x\n",&b ,b );
printf("c - address: %p, value: %x\n",&c ,c );
printf("d - address: %p, value: %x\n",&d ,d );
printf("size: a - %d, b - %d c- %d, d - %d", sizeof(a), sizeof(b), sizeof(c), sizeof(d) );
}
Output:
a - address: 0x7ffc08c5866c, value: a
b - address: 0x7ffc08c58660, value: 8c5866c
c - address: 0x7ffc08c58658, value: 8c58660
d - address: 0x7ffc08c58650, value: 8c58658
which has the difference between the address of a and b as 0xc.
then I add:
int f = 10;
I get this output:
f - address: 0x7fff1945656c, value: a
a - address: 0x7fff19456568, value: a
b - address: 0x7fff19456560, value: 19456568
c - address: 0x7fff19456558, value: 19456560
d - address: 0x7fff19456550, value: 19456558
The difference between the address of a and b changed. Can anyone tell me why?
An int takes 4 bytes and a pointer takes 8 bytes. The pointer also works "best" if its address is a multiple of 8, that is the hex address ends in 8 or 0.
An int likewise has an alignment of 4. So two ints could be stored in the same space as one pointer. When you add f it uses the first 4 bytes and "pushes" a 4 bytes further on. Those bytes were previously unused, so that b could start at an 8-byte boundary.
That still leaves room for the pointer b to start at the same 0-address it used before.

int pointer expressions

#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.

Resources