Why arrays arent pointers

From C

Jump to: navigation, search

$Id: why_arrays_arent_pointers.txt,v 1.12 2009/07/03 20:09:19 db Exp db $

It seems a fair number of beginners to 'c' think pointers and arrays are the same thing. There must be a lot of incompetent teachers around, bad books or mis-reading of what it says in K&R. They aren't the same.

This simple program will illustrate they are not the same very quickly.

       int main()
       {
               char array[100];
               char *ptr = array;
               ptr++;
               array++;
       }

Here is what you get with gcc and with clang.

% gcc -c array.c

array.c: In function 'main':

array.c:7: error: lvalue required as increment operand

% clang -c array.c

array.c:7:22: error: cannot modify value of type 'char [100]'

array++;

13:36, 3 July 2009 (UTC)^

1 diagnostic generated.

So what's this mean?, You can think of array as a blob that has length and the actual data inside it. When a compiler 'sees' an array, the compiler 'knows' the size of the array and where the data inside the array is, a pointer has no such information it simply points to something.

This illustrates the compiler knows about the size of array.

       #include <stdio.h>
       int main()
       {
               char array[100];
               char *ptr = array;
               printf("sizeof array=%zd\n", sizeof(array));
               printf("sizeof ptr  =%zd\n", sizeof(ptr));
       }


% clang -o array2 array2.c

% ./array2

sizeof array=100

sizeof ptr =4

Now where did this confusion about arrays and pointers being the same come from? Section 5.3 of K&R version 2 states: "In C, there is a strong relationship between pointers and arrays, strong enough that pointers and arrays should be discussed simultaneously."

The diagram on the next page shows exactly what is going on, the array is an object known to the compiler, the size and type of it is known, where items are placed inside this object are known. So you can use pointer operations to access items inside the array object, but you cannot use the array object as if it was a pointer.

More confusion comes from the fact that the value of an array is a pointer, because functions in c take parameters by value, the compiler takes the value of the array automatically and passes that into the function.

As K&R puts it "When an array name is passed to a function, what is passed is the location of the initial element."

 #include <stdio.h>
 void func(char subarray[100],char* pointer)
 {
       printf("sizeof subarray=%zd\n", sizeof(subarray));
       printf("address of subarray=%p\n", (void *)subarray);
       printf("pointer            =%p\n", (void *)pointer);
 }
 int main()
 {
       char array[100];
       printf("sizeof of array=%zd\n", sizeof(array));
       printf("address of array=%p\n", (void *)array);
       printf("address of array[0]=%p\n", (void *)&array[0]);
       func(array,array);
 }
        

% clang -o array3 array3.c

% ./array3

sizeof of array=100

address of array=0xbfbfe760

address of array[0]=0xbfbfe760

sizeof subarray=4

address of subarray=0xbfbfe760

pointer =0xbfbfe760

Here we pass an array to a function, the value of the array is a pointer to the initial element, we do not have an array here anymore, and as you see even if you declare it as an array in the called function it is also still converted into a pointer.

Personal tools