de1337ed
de1337ed

Reputation: 3315

Simple pointer arithmetic problems

Question 1:

I was reading the K&R book, and i got a little confused about something. I'm a little confused on some simply pointer arithmetic. If I say

char (*a)[10];

I know that I just declared a pointer to an array of 10 chars. Firstly, because I didn't malloc, this is still all kept on the stack right? So there is this pointer in the stack that is pointing to the start of the char array of size 10 right?

Now, If I want to access the second element in the array, would I still do *(a+2*sizeof(char))? Or would that not work in this case?

Question 2:

If I had

int* a = malloc(10*sizeof(int));

If I wanted to get the second byte from the integer array, I would do:

*((char*)((char*)a+2))

Is this correct?

Thank you.

Upvotes: 1

Views: 1170

Answers (3)

Timothy Jones
Timothy Jones

Reputation: 22125

Question 1:

Firstly, because I didn't malloc, this is still all kept on the stack right?

The pointer is declared on the stack, but it's not pointing to anything yet. You'd need to do something like:

char (*a)[10];
char array[10];
a = &array;

Otherwise a doesn't point to anything, and trying to access it will cause problems.

Now, If I want to access the second element in the array, would I still do *(a+2*sizeof(char))

You don't need to say sizeof(char), since the compiler will work out the size of the addition for you using the type of the pointer or array you're using. Also, if you want the second element, you'll need to add 1 instead of 2 (since arrays/pointers index from zero).

  • If you want the second element from the array you're pointing to, you can do (*a)+1 or alternatively (*a)[1].

  • If your pointer points to more than one array, and you want the second array, then *(a+1) or a[1] is what you want.


Question 2:

(it's really best to open multiple questions next time :)

If I wanted to get the second byte from the integer array, I would do: *((char*)((char*)a+2))?

Firstly, it's important to realise that when you say:

int* a = malloc(10*sizeof(int));

You have a pointer to a block of memory with enough space for 10 integers - which is not an array. If this is confusing, see the C-FAQ on pointers and arrays.

Now, if you want the second byte from the block of memory that a points to, you can just say:

char second_byte = *((char*)a+1);

Because the cast is a higher precedence than the addition, a is treated as a char* when the addition is performed. However, to minimise the chance of misunderstandings when reading the code, I'd probably write:

char second_byte = *(((char*)a)+1);

or better:

char second_byte = ((char*)a)[1];

Instead. Note that the extra cast in the original example is unnecessary.

Upvotes: 1

Eric Z
Eric Z

Reputation: 14505

First Thing First

In C/C++, array index starts from 0 instead of 1. So if you want to access the second element, you use index 1, not 2 !

Answer 1

char (*a)[10];

Yes, this is a pointer to an array of size 10. The pointer itself is on the stack. But it doesn't point to any valid array, for this single line, which means it's unitialized.

To initialize your pointer,

char b[2][10] = {"123456789", "abcdefghi"};
// initialize pointer "a"
char (*a)[10] = b;

To access the "second" element, "2" in this case, you use,

char (*a)[10] = b;
// access the element at 1st row, 2nd column
printf("%c\n", a[0][1]);

Answer 2

You want to access the 2nd byte. However, the element index start from 0 instead of 1, so you should use "+1" instead of "+2" for the 2nd byte!

*((char*)a+1);

Upvotes: 2

Youssef G.
Youssef G.

Reputation: 617

when you declare the pointer, its not pointing to anything quite yet. you will need to declare a size 10 character array and assign its address to (*a)[10] if you want it to be on stack. As for accessing the second element, most compilers you can do *(a+1) for the next element (so for an int which is 4 bytes, *(a+1) is the second element, and *(a+4) is the 4th element (NOT the 4th byte).

char (*a)[10];
char arrayTest[10];
a=&arrayTest;

with your second question, getting the second byte would be the *a and then simply do a rightshift:

char Test= ((*a)&0x7FFF)>>8;

Upvotes: 1

Related Questions