Are pointers and arrays equivalent in C?
Written by Eli Bendersky   
Wednesday, 04 May 2011
Article Index
Are pointers and arrays equivalent in C?
An important difference

 

Variable names in C are just labels

This point is frequently ignored by programmers who don't actually hack on compilers. A variable in C is just a convenient, alphanumeric pseudonym of a memory location. Were we writing assembly code, we would just create a label in some memory location and then access this label instead of always hard-coding the memory value – and this is what the compiler does.

Well, actually the address is not hard-coded in an absolute way because of loading and relocation issues, but for the sake of this discussion we don't have to get into these details.

A label is something the compiler assigns at compile time. From here the great difference between arrays and pointers in C stems. And this is also why...

Arrays passed to functions are converted to pointers

 

Here's a snippet:

void foo(char arr_arg[], char* ptr_arg)
{
char a = arr_arg[7];
char b = ptr_arg[7];
}
Quiz: how are the accesses to a and b different here?

Answer: they're not!

    char a = arr_arg[7];

00412DCE mov eax,dword ptr [arr_arg]
00412DD1 mov cl,byte ptr [eax+7]
00412DD4 mov byte ptr [a],cl

char b = ptr_arg[7];

00412DD7 mov eax,dword ptr [ptr_arg]
00412DDA mov cl,byte ptr [eax+7]
00412DDD mov byte ptr [b],cl

This happens because arrays passed into functions are always converted into pointers. The argument declaration char arr_place[] is just syntactic sugar for char* arr_place. And, by the way, so is char arr_place[100]. The size makes no difference to the C compiler – it's still converted to a pointer.

To quote from Chapter 5 of K&R2, The C Programming Language by Brian Kernighan and Dennis Ritchie, 1988 (see side panel) :

 

When an array name is passed to a function, what is passed is the location of the initial element. Within the called function, this argument is a local variable, and so an array name parameter is a pointer, that is, a variable containing an address.

 

If this seems strange, think again. Recall the diagrams of the previous section. The C compiler has no choice here, since an array name is a label it replaces at compile time with the address it represents. But a function isn’t called at compile time, it’s called at run time, where something should be placed on the stack to be considered as an argument. The compiler can’t just treat array references inside a function as labels and replace them with addresses, because it has no idea what actual array will be passed in at run time.

This last point may be a bit convoluted, but it’s not critical to the understanding of the article. You can just take it as a fact: arrays passed to functions are converted to pointers, end of story!

Does the difference affect me?

Yes.

One way is that arrays just can’t be manipulated the way pointers can. Here’s a quote from by Van der Linden's Expert C Programming:

There is one difference between an array name and a pointer that must be kept in mind. A pointer is a variable, so pa=a and pa++ are legal. But an array name is not a variable; constructions like a=pa and a++ are illegal.

Here’s an example:

#include <stdio.h>

int main()
{
    int i;
    char array[] = "don't panic";
    char* ptr = array;

    /* array traversal */
    for (i = 0; i < sizeof(array); ++i)
        printf("%c ", array[i]);

    printf("\n");

    /* pointer traversal */
    for (; *ptr; ++ptr)
        printf("%c ", *ptr);

    return 0;
}

Note how an array has to be indexed with another variable. A pointer, on the contrary, is just a variable that can be manipulated freely.

Another, more important, difference is actually a common C gotcha:

Suppose one file contains a global array:

char my_arr[256];

And soothed by the seeming equivalence between arrays and pointers, the programmer who wants to use it in another file mistakenly declares as:

extern char* my_arr;

When he tries to access some element of the array using this pointer, he will most likely get a segmentation fault or a fatal exception (the nomenclature depends on the OS). Understanding why this happens is left as an exercise to the reader.

Hint: look at the first assembly listing in this article. How will the element be accessed via the pointer? What’s going to happen if it’s not actually a pointer but an array?

 

personalheader

 

This article was originally published as  on Eli Bendersky's website and has been posted here with kind permission of the author.

<ASIN:0131103628>

<ASIN:0131774298>



Last Updated ( Wednesday, 04 May 2011 )