Thursday, January 12, 2012

Arrays are NOT pointers

Arrays are constant pointers:
A static one-dimensional array in C is represented by a constant pointer, which holds the base address of the array and points to a statically allocated memory segment that stores the array items. The indexing expressions of type x[i] are translated by C/C++ compilers into indirection expressions of type *(x+i). For these reasons, the size of an array is unknown at run time and so a run-time index range check cannot be performed. Only a simple compile-time index range check is performed by C/C++ compilers (e.g., during initialization). 

Why array arguments are still passed by value:
Another consequence of the representation of arrays as pointers concerns passing of array arguments to functions. Though C can only perform passing by value and though the C++ default is also passing by value (passing by reference must be explicitly stated), it is actually the pointer representing the array that is passed by value, and this value (the so-called base address of the array) is then used to access the actual array. This results in the possibility of a function modifying the array that has been passed to it.

Because indexing expressions are translated into indirection expressions, all pointers (with the exception of void*) can be indexed. Pointers can therefore be regarded as "arrays without bodies" and hence a body can be provided dynamically. A dynamic one-dimensional array is a pointer that points to a dynamically allocated segment to store the array items. Such arrays behave in all respects as static ones, but they can be extended or reduced if need be. Common errors associated with the use of dynamic arrays include (a) using the pointer without allocating the segment to store the array items ("uninitialized pointer" error), (b) allocating insufficient storage ("overflow" error), and (c) forgetting to deallocate unneeded dynamic arrays or unneeded segments that may lead to memory leaks.

Array Reference vs Pointer Reference:

The address of array is known at compiletime. So if the compiler needs to do something with an address (add an offset to it, perhaps), it can do that directly and does not need to plant code to retrieve the address first. In contrast, the address of pointer is not known at compile time and not the address of the value poitnted by pointer;thus the current value of a pointer must be retrieved at runtime before it can be dereferenced (made part of a further look-up).

That's why we can equally write extern char a[]; as well as extern char a[100];.
Both declarations indicate that a is an array, namely a memory location where the characters in the
array can be found. The compiler doesn't need to know how long the array is in total, as it merely
generates address offsets from the start. To get a character from the array, you simply add the
subscript to the address that the symbol table shows a has, and get what's at that location

Array is defined as an Array and referenced as a pointer:

file 1
int p[100]; //defined as array

file 2
extern char *p; //referenced as pointer

If you declare extern char *p, it tells the compiler that p is a pointer (a four-byte
object on many contemporary machines), and the object pointed to is a character. To get the character, you have to get whatever is at address p, then use that as an address and get whatever is there. Pointer accesses are more flexible, but at the cost of an extra fetch instruction

When we retrieve the contents of p[i] (starting at where p points, step forward over 'i' things, each of which is a char) using the extern, we get characters, but we treat it as a pointer. Interpreting ASCII characters as an address is garbage, and if you're lucky the program will coredump at that point. If you're not lucky it will corrupt something in your address space, causing a mysterious failure at some later point in the program.

Thus,

char * p = "abcdefgh"; ... p[3]  

char a[] = "abcdefgh"; ... a[3]

They both get you a character 'd' but they get there by very different look-ups.

Reason why Array & Pointers are not same :
the following two are same:
ptr=&my_array[0];
ptr=my_array;
The above doesnt means pointers and arrays are same
while we can write ptr=my_array;
we cant write my_array=ptr;The reason being while ptr is a variable,my_array is a constant.i.e the location at which the first element of my_array will be stored cant be changed once my_array[] has been declared.Here comes the concept of unmodifiable lvalue;Though my_array is a named region of storage its not a modifiable lvalue.

Concept behind Array names referred a Constants:
int i,k;
i=2;
k=i;
i is a variable and occupies space in data section of memory whereas 2 is a constant and instead of setting aside memory in the data segment ,it is embedded directly in the code segment of memory.That is k=i; tells the compiler to create code which at run time will look at memory location &i to determine the value to be moved to k;but i=2; simple puts the 2 in the code and there is no referencing of data segment;Both k & i are objects,but 2 is not an object
Similarly since my_array is a constant once the compiler establishes where the array itself is to be stored,it knows the address of my_array[0] and on seeing ptr=my_array; it simply uses this as a constant in the code segment and there is no referencing of the data segment beyond that.

No comments:

Post a Comment