why address of pointer is machine dependent?

H

henry

List,

I have following address of pointer addition.
{
int *ptr, a=5;
int **pptr;
ptr = &a;

//assume address of pointer ptr, &ptr=0x9000
*pptr = &ptr + 0x100;

printf("pptr = %p\n",pptr);
}

pptr = 0x9400 for 32-bit machine instead 0x9100.
Why 0x100 *4 bytes must apply for pptr?

Thanks.

---henry
 
S

Stephen Sprunk

henry said:
List,

I have following address of pointer addition.
{
int *ptr, a=5;
int **pptr;
ptr = &a;

//assume address of pointer ptr, &ptr=0x9000
*pptr = &ptr + 0x100;

printf("pptr = %p\n",pptr);
}

pptr = 0x9400 for 32-bit machine instead 0x9100.
Why 0x100 *4 bytes must apply for pptr?

Because, apparently, sizeof(int *)==4 on the machine you ran the code
on, which is almost always the case today for a "32-bit machine" with
8-bit bytes (i.e. 32/8==4).

S
 
K

Keith Thompson

henry said:
I have following address of pointer addition.
{
int *ptr, a=5;
int **pptr;
ptr = &a;

//assume address of pointer ptr, &ptr=0x9000
*pptr = &ptr + 0x100;

printf("pptr = %p\n",pptr);
}

pptr = 0x9400 for 32-bit machine instead 0x9100.
Why 0x100 *4 bytes must apply for pptr?

Because that's how pointer arithmetic works. See section 4 of the
comp.lang.c FAQ, <http://www.c-faq.com/>, or any decent C textbook.
 
H

hal2k

Acutally is not but I understand your confusion.
int *y, *x;
x = y + 10;
This means x = point(y) + sizeof(int)*10;
So in 32-bit all pointers are dword(4 bytes), 4*0x100 = 0x400On

2009-03-05, henry
 
H

henry

Acutally is not but I understand your confusion.
int *y, *x;
x = y + 10;
This means x = point(y) + sizeof(int)*10;
So in 32-bit all pointers are dword(4 bytes), 4*0x100 = 0x400On

2009-03-05, henry


I have another example,

int assy[3]={1,2,3};
char kb[3]={'a','b','c'};

printf("address of arry of int = %p, %p, %p\n",assy,assy+1,assy+2);
printf("address of arry of char = %p, %p, %p\n",kb,kb+1,kb+2);

And I got following print out and it is not following sizeof(int)*:

address of arry of int = 0xbf9af580, 0xbf9af584, 0xbf9af588
address of arry of char = 0xbf9af57d, 0xbf9af57e, 0xbf9af57f

---henry
 
K

Keith Thompson

henry said:
I have another example,

int assy[3]={1,2,3};
char kb[3]={'a','b','c'};

printf("address of arry of int = %p, %p, %p\n",assy,assy+1,assy+2);
printf("address of arry of char = %p, %p, %p\n",kb,kb+1,kb+2);

And I got following print out and it is not following sizeof(int)*:

address of arry of int = 0xbf9af580, 0xbf9af584, 0xbf9af588
address of arry of char = 0xbf9af57d, 0xbf9af57e, 0xbf9af57f

No, it's following sizeof(int).

If you have a pointer of type int*, and int is 4 bytes, then adding 1
to that pointer value advances the pointed-to address by 4 bytes.

The most important thing to keep in mind is that *pointers are not
integer*. A few of the arithmetic operations that apply to integers
are defined for pointers, but they don't mean the same thing. Adding
1 to an integer gives you the next mathematical integer value; adding
1 to a pointer foo advances to the next foo object, whatever the size
of a foo object happens to be. (Pointers are often, but not always,
implemented as integers.)
 
M

Martin Ambuhl

henry said:
I have another example,
But not of compilable code.
int assy[3]={1,2,3};
char kb[3]={'a','b','c'};

printf("address of arry of int = %p, %p, %p\n",assy,assy+1,assy+2);
printf("address of arry of char = %p, %p, %p\n",kb,kb+1,kb+2);

These are both wrong. The specifier "%p" is for printing
pointers-to-void. None of the arguments you supply are of that type.
See my code below.
And I got following print out and it is not following sizeof(int)*:

What is that '*' doing in the line above, and how would you know that
"it is not following sizeof(int)"?
The lines below suggest just the opposite.
address of arry of int = 0xbf9af580, 0xbf9af584, 0xbf9af588
address of arry of char = 0xbf9af57d, 0xbf9af57e, 0xbf9af57f

Copy the code below and run it on your implementation. If you do not
have the specifier "%zu", you can, _with this example_, safely replace
it with %u and cast the arguments to (unsigned). I have provided after
the code the output on my implementation. If you study the code and the
output a light should flash and your confusion disappear.

#include <stdio.h>

int main(void)
{
int assy[] = { 1, 2, 3 };
char kb[] = { 'a', 'b', 'c' };
char *cptr;
size_t i;


cptr = kb;
printf("'kb' is an array char[], with sizeof kb = %zu\n"
"It has sizeof kb / sizeof *kb = %zu elements, "
"each of size *kb = %zu\n"
"I have set the char * cptr = kb.\n", sizeof kb,
sizeof kb / sizeof *kb, sizeof *kb);
for (i = 0; i < sizeof kb / sizeof *kb; i++)
printf("&kb[%zu] = %p, kb+%zu = %p, cptr+%zu*sizeof *kb = %p\n",
i, (void *) &kb,
i, (void *) (kb + i),
i, (void *) (cptr + i * sizeof *kb));
putchar('\n');

cptr = (char *) assy;
printf("'assy' is an array int[], with sizeof assy = %zu\n"
"It has sizeof assy / sizeof *assy = %zu elements, "
"each of size *assy = %zu\n"
"I have set the char * cptr = (char *)assy.\n", sizeof assy,
sizeof assy / sizeof *assy, sizeof *assy);
for (i = 0; i < sizeof assy / sizeof *assy; i++)
printf
("&assy[%zu] = %p, assy+%zu = %p, cptr+%zu*sizeof *assy =
%p\n",
i, (void *) &assy, i, (void *) (assy + i), i,
(void *) (cptr + i * sizeof *assy));
return 0;


}


[Output]

'kb' is an array char[], with sizeof kb = 3
It has sizeof kb / sizeof *kb = 3 elements, each of size *kb = 1
I have set the char * cptr = kb.
&kb[0] = dff99, kb+0 = dff99, cptr+0*sizeof *kb = dff99
&kb[1] = dff9a, kb+1 = dff9a, cptr+1*sizeof *kb = dff9a
&kb[2] = dff9b, kb+2 = dff9b, cptr+2*sizeof *kb = dff9b

'assy' is an array int[], with sizeof assy = 12
It has sizeof assy / sizeof *assy = 3 elements, each of size *assy = 4
I have set the char * cptr = (char *)assy.
&assy[0] = dff9c, assy+0 = dff9c, cptr+0*sizeof *assy = dff9c
&assy[1] = dffa0, assy+1 = dffa0, cptr+1*sizeof *assy = dffa0
&assy[2] = dffa4, assy+2 = dffa4, cptr+2*sizeof *assy = dffa4
 
R

Richard

Martin Ambuhl said:
henry said:
I have another example,
But not of compilable code.
int assy[3]={1,2,3};
char kb[3]={'a','b','c'};

printf("address of arry of int = %p, %p, %p\n",assy,assy+1,assy+2);
printf("address of arry of char = %p, %p, %p\n",kb,kb+1,kb+2);

These are both wrong. The specifier "%p" is for printing
pointers-to-void. None of the arguments you supply are of that
type. See my code below.
And I got following print out and it is not following sizeof(int)*:

What is that '*' doing in the line above, and how would you know that
"it is not following sizeof(int)"?
The lines below suggest just the opposite.
address of arry of int = 0xbf9af580, 0xbf9af584, 0xbf9af588
address of arry of char = 0xbf9af57d, 0xbf9af57e, 0xbf9af57f

Copy the code below and run it on your implementation. If you do not
have the specifier "%zu", you can, _with this example_, safely replace
it with %u and cast the arguments to (unsigned). I have provided
after the code the output on my implementation. If you study the code
and the output a light should flash and your confusion disappear.

#include <stdio.h>

int main(void)
{
int assy[] = { 1, 2, 3 };
char kb[] = { 'a', 'b', 'c' };
char *cptr;
size_t i;


cptr = kb;
printf("'kb' is an array char[], with sizeof kb = %zu\n"
"It has sizeof kb / sizeof *kb = %zu elements, "
"each of size *kb = %zu\n"
"I have set the char * cptr = kb.\n", sizeof kb,
sizeof kb / sizeof *kb, sizeof *kb);
for (i = 0; i < sizeof kb / sizeof *kb; i++)
printf("&kb[%zu] = %p, kb+%zu = %p, cptr+%zu*sizeof *kb = %p\n",
i, (void *) &kb,
i, (void *) (kb + i),
i, (void *) (cptr + i * sizeof *kb));
putchar('\n');

cptr = (char *) assy;
printf("'assy' is an array int[], with sizeof assy = %zu\n"
"It has sizeof assy / sizeof *assy = %zu elements, "
"each of size *assy = %zu\n"
"I have set the char * cptr = (char *)assy.\n", sizeof assy,
sizeof assy / sizeof *assy, sizeof *assy);
for (i = 0; i < sizeof assy / sizeof *assy; i++)
printf
("&assy[%zu] = %p, assy+%zu = %p, cptr+%zu*sizeof *assy =
%p\n",
i, (void *) &assy, i, (void *) (assy + i), i,
(void *) (cptr + i * sizeof *assy));
return 0;


}


[Output]

'kb' is an array char[], with sizeof kb = 3
It has sizeof kb / sizeof *kb = 3 elements, each of size *kb = 1
I have set the char * cptr = kb.
&kb[0] = dff99, kb+0 = dff99, cptr+0*sizeof *kb = dff99
&kb[1] = dff9a, kb+1 = dff9a, cptr+1*sizeof *kb = dff9a
&kb[2] = dff9b, kb+2 = dff9b, cptr+2*sizeof *kb = dff9b

'assy' is an array int[], with sizeof assy = 12
It has sizeof assy / sizeof *assy = 3 elements, each of size *assy = 4
I have set the char * cptr = (char *)assy.
&assy[0] = dff9c, assy+0 = dff9c, cptr+0*sizeof *assy = dff9c
&assy[1] = dffa0, assy+1 = dffa0, cptr+1*sizeof *assy = dffa0
&assy[2] = dffa4, assy+2 = dffa4, cptr+2*sizeof *assy = dffa4


Alternatively use a debugger and have it show you all that with no
programming required.
 
D

Default User

henry wrote:

I have another example,

int assy[3]={1,2,3};
char kb[3]={'a','b','c'};

printf("address of arry of int = %p, %p, %p\n",assy,assy+1,assy+2);
printf("address of arry of char = %p, %p, %p\n",kb,kb+1,kb+2);

And I got following print out and it is not following sizeof(int)*:

address of arry of int = 0xbf9af580, 0xbf9af584, 0xbf9af588
address of arry of char = 0xbf9af57d, 0xbf9af57e, 0xbf9af57f

What you are experiencing is sometimes called the "stride" of the
pointer. That means the number of bytes the pointer will advance when
an integer value is added to a pointer. This will be the size of the
type the pointer points to, not the pointer itself.

The reason for this is simple, so that you can do random access of a
sequence of objects without complex pointer addition.

Any decent C text should explain this. Which one are you using that
doesn't cover this topic?




Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top