An array of pointers or a pointer of arrays?

By | April 7, 2016

There is a very subtle difference in the following:

int *myarray[10] v's int (*myarray)[10]

The first declaration is interpreted as an array of 10 integers, that are pointers. That is you have 1 array holding 10 pointers that are of type integer.

The square brackets have a higher precedence so the myarray[10] gets defined first.

The second statement says myarray is a pointer (evaluating the brackets first) and it points to an array.

Back to basics

Here is a simple piece of code declaring an array of 10 chars. Each char is 1 byte by default. And copies into the array a 3 character string “foo”.

It then prints out name as a string (note that names is actually a pointer to the first element names[0]) and the %s qualifier tells the program to print a string.

To print just 1 character, use the %c qualifier and specify a character position such as names[1].

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[]){
 char names[10];
 strcpy(names, "foo");
 printf("%s\n", names);
 printf("%c\n", names[1]);
}

Output

>> foo
>> o

 

int (*myarray)[10]

Working with pointers to an array is a slightly different proposition. If you do:

 char (*names)[10];
 strcpy(names, "foo");

you will get an error of:

incompatible pointer types passing ‘char (*)[10]’ to parameter of type ‘char *’

because strcpy is expecting a “char *” input. To get around this you can use the memcpy function because memcpy can take a void pointer as an input.

void *memcpy(void *str1, const void *str2, size_t n)

The trick with memcpy though is that you have to allocate some memory first via malloc.

names = malloc(10 * 4);

If you don’t, your good old friend Seg Fault will come and visit. (Segmentation fault: 11). Here is the new code for main.

 char (*names)[10];
 names = malloc(10 * 4);
 memcpy(names, "sue", 3);
 printf("%s\n", (*names));
 printf("%c\n", (*names)[1]);

This will print:

>> sue
>> u

Note that memcpy(names, “sue”, 3) and memcpy(names[0], “sue”, 3) are equivalent because the name of the array and the first element of an array both have the same pointer value.

Getting Funky

Let’s try this:

memcpy(names[1], "sue", 3);

I’m placing “sue” in the second block of 10 bytes of the names array. To print this out, I’ll need to point to this second position.

printf("%s\n", (*(names+1)));

A picture might help here.

Screen Shot 2016-04-05 at 8.15.09 AM

Screen Shot 2016-04-05 at 8.14.37 AM

“sue” in hex has moved 10 bytes. 0x00 is 1 byte so count 10 sets of 00.

To print out the u character, do:

printf(“%c\n”, (*(names+1))[1]);

Notes

To allocate values to a pointer to an array, the assignment operator (=) cannot be used.

char (*names)[32];
names[0] = "James";

This won’t work and will result in “error: array type ‘char [32]’ is not assignable”. This is because arrays are not assignable. The strcpy or memcpy function has to be used from string.h library.

 

Leave a Reply

Your email address will not be published. Required fields are marked *