Velocity Reviews > Array address arithmetic

vjay
Guest
Posts: n/a

 12-09-2007
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression ptr =
(char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
and (a + 1) in the above mentioned expression.Help guys its confusing.

--

Tomás Ó hÉilidhe
Guest
Posts: n/a

 12-09-2007
"vjay" <(E-Mail Removed)> wrote in

> Check the code below guys
> void main()

int main(void)

> {
> char a[5] = {1,2,3,4,5};

Unusual to store numbers in a char, but how and ever.

> char *ptr;
> ptr = (char*)(&a + 1);

Here you take the address of the array "a", and add one to it. This will
give you the address of the first byte after the fifth element in the
array "a".

> printf("%d",*(ptr-1));

"ptr-1" leaves you with the address of the fifth element in "a".

> The output of the program is 5
>
> But what i expected was 1.When i replace &a with a in the expression
> ptr = (char*)(a + 1); i get output as 1.what is the difference between
> (&a + 1) and (a + 1) in the above mentioned expression.Help guys its
> confusing.

Pointer arithmetic depends on the size of the "pointed to" type. The
size of the "pointed to" type in &a is "sizeof(char[5])".

--
Tomás Ó hÉilidhe

James Fang
Guest
Posts: n/a

 12-09-2007
On 12ÔÂ9ÈÕ, ÏÂÎç10Ê±43·Ö, "vjay" <(E-Mail Removed)> wrote:
> Check the code below guys
> void main()
> {
> char a[5] = {1,2,3,4,5};
> char *ptr;
> ptr = (char*)(&a + 1);
> printf("%d",*(ptr-1));
>
> }
>
> The output of the program is 5
>
> But what i expected was 1.When i replace &a with a in the expression ptr =
> (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
> and (a + 1) in the above mentioned expression.Help guys its confusing.
>
> --

try the following:
int main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)((char*)&a + 1);
printf("%d",*(ptr-1));
getchar();
}

Anthony Fremont
Guest
Posts: n/a

 12-09-2007
vjay wrote:
> Check the code below guys
> void main()
> {
> char a[5] = {1,2,3,4,5};
> char *ptr;
> ptr = (char*)(&a + 1);

Don't you mean this:
ptr = (char *)(&a[0] + 1);

Didn't you get some kind of warning? What compiler are you using?

> printf("%d",*(ptr-1));
> }
>
> The output of the program is 5
>
> But what i expected was 1.When i replace &a with a in the expression
> ptr = (char*)(a + 1); i get output as 1.what is the difference
> between (&a + 1) and (a + 1) in the above mentioned expression.Help
> guys its confusing.

Noé Falzon
Guest
Posts: n/a

 12-09-2007
vjay a écrit :
> Check the code below guys
> void main()
> {
> char a[5] = {1,2,3,4,5};
> char *ptr;
> ptr = (char*)(&a + 1);
> printf("%d",*(ptr-1));
> }
>
> The output of the program is 5
>
> But what i expected was 1.When i replace &a with a in the expression ptr =
> (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
> and (a + 1) in the above mentioned expression.Help guys its confusing.

I would say it is because &a is a pointer to an array of 5 chars, and
thus (&a + 1) add the size of one array of 5 chars. It brings you one
char after the 5.
Then ptr being a pointer to a char, doing (ptr-1) brings you one char
back, right on the 5.

I think you meant (a+1). This way, it would have worked. The name of the
array is a pointer to its first element. So "a" is really a pointer to a
char, and (a+1) points to the second element of your array.

It's all due to the difference between a pointer to a char ("a"), and a
pointer to an array of chars ("&a").

Hope i'm not mistaken,
Noé

James Kuyper
Guest
Posts: n/a

 12-09-2007
vjay wrote:
> Check the code below guys
> void main()
> {
> char a[5] = {1,2,3,4,5};
> char *ptr;
> ptr = (char*)(&a + 1);
> printf("%d",*(ptr-1));
> }
>
> The output of the program is 5
>
> But what i expected was 1.When i replace &a with a in the expression ptr =
> (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
> and (a + 1) in the above mentioned expression.Help guys its confusing.

When you add an integer n to a pointer to a given type, the result is a
new pointer pointing that n elements of that type farther down. The
expression &a has the type char(*)[5], which means it points at an
entire array of 5 chars. Therefore, when you add 1 to it, it points at
the next array of 5 characters. Converting it to char* result in a
pointer that would point at the first char of that next array. When you
subtract 1, the behavior is undefined; however, on most real-world
implementations, the actual behavior is to point at the last char of the
previous array, which contained a 5.

In the expression (a+1), the name of the array decays into a pointer to
the first element of the array, and therefore has the type char*. When
you add 1 to that pointer, it points at the next char. When you subtract
1, it goes back to pointing at the first char, as you expected.

James Kuyper
Guest
Posts: n/a

 12-09-2007
Anthony Fremont wrote:
> vjay wrote:
>> Check the code below guys
>> void main()
>> {
>> char a[5] = {1,2,3,4,5};
>> char *ptr;
>> ptr = (char*)(&a + 1);

>
> Don't you mean this:
> ptr = (char *)(&a[0] + 1);
>
> Didn't you get some kind of warning? What compiler are you using?

On what basis? If you were writing the text of the warning message, what
would it say? As far as I can see, the only thing wrong with this code
is vjay's incorrect understanding of what it does.

Anthony Fremont
Guest
Posts: n/a

 12-09-2007
James Kuyper wrote:
> Anthony Fremont wrote:
>> vjay wrote:
>>> Check the code below guys
>>> void main()
>>> {
>>> char a[5] = {1,2,3,4,5};
>>> char *ptr;
>>> ptr = (char*)(&a + 1);

>>
>> Don't you mean this:
>> ptr = (char *)(&a[0] + 1);
>>
>> Didn't you get some kind of warning? What compiler are you using?

>
> On what basis? If you were writing the text of the warning message,
> what would it say? As far as I can see, the only thing wrong with
> this code is vjay's incorrect understanding of what it does.

Thanks, I get it now, I guess I just never had a need to try such a thing
before.

pete
Guest
Posts: n/a

 12-09-2007
vjay wrote:
>
> Check the code below guys
> void main()
> {
> char a[5] = {1,2,3,4,5};
> char *ptr;
> ptr = (char*)(&a + 1);
> printf("%d",*(ptr-1));
> }
>
> The output of the program is 5
>
> But what i expected was 1.When i replace &a with a in the expression ptr =
> (char*)(a + 1); i get output as 1.
> what is the difference between (&a + 1)
> and (a + 1) in the above mentioned expression.Help guys its confusing.

ptr == a + 5
(char*)(&a + 1) == a + 5
&a + 1 == (char(*)[5])(a + 5)

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
char a[5] = {1,2,3,4,5};
char *ptr = (char*)(&a + 1);

if ( ptr == a + 5) {
puts("ptr == a + 5");
}
if ( (char*)(&a + 1) == a + 5) {
puts("(char*)(&a + 1) == a + 5");
}
if ( &a + 1 == (char(*)[5])(a + 5)) {
puts("&a + 1 == (char(*)[5])(a + 5)");
}
return 0;
}

/* END new.c */

--
pete

Joe Wright
Guest
Posts: n/a

 12-09-2007
vjay wrote:
> Check the code below guys
> void main()
> {
> char a[5] = {1,2,3,4,5};
> char *ptr;
> ptr = (char*)(&a + 1);
> printf("%d",*(ptr-1));
> }
>
> The output of the program is 5
>
> But what i expected was 1.When i replace &a with a in the expression ptr =
> (char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
> and (a + 1) in the above mentioned expression.Help guys its confusing.

You've been hanging out here for a while now haven't you? Why do you not
grasp what everybody is telling you? What you have posted is not
compilable and also incorrect. Watch ..

#include <stdio.h>

int main(void)
{
char a[5] = {1, 2, 3, 4, 5};
char *ptr;
ptr = (char *) (&a + 1);
printf("%d", *(ptr - 1));
return 0;
}

Now it's compilable and correct.
Expressing &a gives an address of type 'array 5 of char'. (&a + 1) gives
the address of the 'next' array 5 of char. You cast this address to
char* and store it in ptr. This effectively points one past the end of
array a. ptr - 1 points to the end of a and *(ptr - 1) is a[4] with value 5.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---