tags:

views:

118

answers:

5

I've just read this that by pointing a pointer to the first array member, you can cycle through by adding to the pointer.

char my_array[] = "I am an array of chars";

char *my_pointer = my_array;

printf("%c\n", *my_pointer);

my_pointer++;

printf("%c", *my_pointer);

I guess this implies array members are always stored sequentially, and the space allocated is always reserved and an array's size can not be extended (because after the length it may contain other things in memory)?

Why does this work exactly? When accessing an array using a subscript, like my_array[5], will C only know where the array starts (i.e. my_array[0]), and have to increase an internal pointer by 5 to return it?

I apologize if this seems obvious, but I've spent my life in high level languages and C is very interesting to me.

+2  A: 

This nice answer might help

RC
A: 

I'm sorry, but there are a few mistakes in your example provided.

You need to declare my_array as

char my_array[] = "string...";

and get rid of either the & or the [0] in the second line (both have same effect).

you need to change the * in the 3rd and 5th lines to a & or a [0] (again, same effect).

The reason that this happens is because a string (array of char's) is a series of chars in memory. The char* points to the first one, so incrementing it will make it point to the second, third, ect...

You could increment it past the end of the string to see what else is stored in your app's memory (but this could crash your program).

-Alex

Alexander Rafferty
harper
Alexander Rafferty
` the address of the whole array has type ‘pointer to array of n elements of type T’"
detly
caf
Although I may have misunderstood your comment there @Alexander Rafferty
detly
Alexander Rafferty
detly
Thanks, I have tried to update the code in the question to be correct.
alex
+1  A: 
Hitesh
A: 

my_pointer point to a string in memory. Each CHAR is 1 byte. So my_pointer++ will look at the next byte and hence the next character. The read my_pointer++ as a string it will continue through memory until it finds null as all strings should be null terminated.

fyi

my_pointer += sizeof(type_of_array) will go to the next item in the array so long as you cast the pointer correctly.

malloc can be used to manage the memory available to your program. This takes care of finding free memory space to allocate the object to.

Matthew
no, my_pointer++ will increment the pointer by the size of data type. This is a handy feature of C++, as it allows us to forget about the size of the data type an array is pointing to. So, if float* a = (float*)1000; (hypothetically) then a++; would make a=1004;
Alexander Rafferty
Um the OP posted about C not C++.
Matthew
+7  A: 

Putting aside the problems with your code, yes, arrays are contiguous elements.

What happens with the second line of the code snippet below:

int * iptr = malloc (40 * sizeof(int));
int x = iptr[10];

is thus:

  • the value 10 is multiplied by the size of the int to get 70 (in this example, we assume a 7-byte int).
  • this is then added to the base pointer iptr (unscaled) and the (7-byte) value is extracted from that location.

This scaling is an important feature. You won't see it when you're working with char arrays but the values &(iptr[0]) and &(iptr[1]) will be separated by the size of an int, not a char (7 in our example case above).

When you add 1 to a pointer, that doesn't actually add 1, it adds the size of the underlying data type. So that:

int *p = &(iptr[0]);
p++;

won't give you an address corresponding to the second byte of that memory, it will actually give you the address of the second int (the seventh byte).

To that end, iptr[3] is exactly equivalent to *(i+3) in that they both give you element number three, even though it's made up of bytes from offset 21 through 27 inclusive.


Pre-emptive strike, just in case: keep in mind that a byte in ISO C is not necessarily 8 bits. ISO uses the term octet for that. A byte is the size of a char.

paxdiablo
`%p` requires the pointer to be cast to `(void *)` (the usual implicit conversion doesn't happen because it's part of the variable argument list).
caf
I am pretty sure that arrays are allocated contiguously. If they weren't, then [] wouldn't work.
Alexander Rafferty
Actually you're right, @Alex. I envisaged a scenario where element could be stored at only even physical addresses (leaving odd ones blank) and the C compiler would automatically skip odd ones when doing its calculations. That would work, but I was trying to be too clever by half :-) C99 specifically states "An array type describes a contiguously allocated ..." so, regardless of what would happen at the hardware level, the C "machine" only knows about its own level. Fixed.
paxdiablo