Pointer Upcast and Downcast

converting integer pointer to char pointer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
	int* ptrInt;
	char * ptrChar;
	void* ptrVoid;
	unsigned char indx;
	int sample = 0x12345678;

	ptrInt = &sample;
	ptrVoid = (void *)(ptrInt);
	ptrChar = (char *)(ptrVoid);
	
	/*manipulating ptrChar */
	for (indx = 0; indx < 4; indx++)
	{
		printf ("\n Value: %p \t Address: %p", *(ptrChar + indx), ( ptrChar + indx)); 
	}
}


Output:

 Value: 00000078         Address: 0022FF74
 Value: 00000056         Address: 0022FF75
 Value: 00000034         Address: 0022FF76
 Value: 00000012         Address: 0022FF77


Question:
Why was sample divided into char sized data? And when pointer arithmetic is performed, how was it able to get its remaining value? How this was possible?

Converting from char pointer to int pointer

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
	unsigned int * ptrUint;
	void * ptrVoid;
	unsigned char sample = 0x08;

	ptrVoid = (void *)&sample;
	ptrUint = (unsigned int *) ptrVoid;

	printf(" \n &sample: %p \t ptrUint: %p ", &sample, ptrUint );
	printf(" \n sample: %p \t *ptrUint: %p ", sample, *ptrUint );  
}

Output

&sample: 0022FF6F       ptrUint: 0022FF6F
 sample: 00000008        *ptrUint: 22FF6F08    <- Problem Point


Question:
Why is it that there is a garbage value in *ptrUint? Why does the garbage value similar to ptrUint? How do you remove the garbage value in the first place?
Last edited on
Why was sample divided into char sized data?


Because you're using a char pointer. If you have in int pointer, it uses int-sized data. If you have a char pointer you get char sized data.

Why is it that there is a garbage value in *ptrUint?


Because you screwed up:

1
2
ptrVoid = (void *)&sample;  // <- you forgot the &
ptrUint = (unsigned int *) ptrVoid;

Last edited on
Sorry, I was not able to add "&" in the post. I will not be able to show you the output if I screwed up, because there is a casting error which prevents compilation. Anyways, I was wondering
if pointer variables has a different take in data widening. For, example:

1
2
3
4
5
6
7
8
9
10
11
	unsigned int uIntVar;
	unsigned char uCharVar = 0x08;

	unsigned int * ptrUint;
	void * ptrVoid;
	unsigned char sample = 0x08;

	uIntVar = (unsigned int )(uCharVar);    <- compiler widens 0x08 to 0x00000008

	ptrVoid = (void *)&sample;
	ptrUint = (unsigned int *) ptrVoid;        <- compiler widens 0x08 to 0x22FF6F08


So, the only way to do this, is to perform masking to rid off the garbage values?
Last edited on
Anyways, I was wondering if pointer variables has a different take in data widening


Kind of... yeah. The thing that's different is that pointers don't widen the variable. They just read from the memory you give them.

When you allocate space for an unsigned char, that gives you 1 byte of memory. If you cast the pointer so the compiler thinks it's pointing to an int, it will attempt to read 4 bytes from memory. However only 1 of those bytes is the char... the other 3 are garbage (or possibly values from other variables).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// let's say that this is some random block of memory:
//  FF EE FF EE FF EE FF EE

// we allocate one byte:
unsigned char b;

// the compiler decides to put b here:
//  FF EE FF EE FF EE FF EE
//           ^
//           b

// change the value of b:
b = 8;

// since 'b' is only 1 byte wide, this only changes
//  1 byte of memory:
//  FF EE FF 08 FF EE FF EE
//           ^
//           b


// now if we do some nasty pointer stuff:
unsigned int* p = (unsigned int*)(&b);

// now p points to the same memory that 'b' uses
//  to see, we can print it:

cout << hex << *p;

// since sizeof(*p) is 4 bytes, this prints 4 bytes of memory
//  starting from address p:
//  FF EE FF 08 FF EE FF EE
//           ^^ ^^ ^^ ^^
//           b
//
//  so FFEEFF08 is printed 
Topic archived. No new replies allowed.