简体   繁体   中英

Memory allocation for pointer to a char array

would someone please explain the difference between

char *names[3] 

and

char (*names)[3] 

and how to read this operators?
If I want to allocate memory for them dynamically how to do so?

For the first case, I think it's just an array of char* of length 3, so no memory allocation not applicable. But in second case how to do memory allocation?

When faced with questions like this, you can usually turn to cdecl (online version here ):

cdecl> explain char *names[3]
declare names as array 3 of pointer to char

cdecl> explain char (*names)[3]
declare names as pointer to array 3 of char

So the former creates array of three pointers-to-char:

+----------+
| names[0] | -> char
|      [1] | -> char
|      [2] | -> char
+----------+

And the latter creates a single pointer to a char array of size three.

+-------+
| names | -> char, char, char - no, not a dance step :-)
+-------+

The second line decodes as "declare names as pointer to array 3 of char".

I've been writing C for over 25 years, and I've never used such a variable.

Anyway, I guess this should work:

char data[3];
char (*names) = data;

Note that the variable name, names , is highly misleading since the variable holds only 3 single characters, as opposed to char *names[3] which is three pointers to characters and thus easily could be used to hold three strings.

Also note that the above code makes little sense, you could just use data directly if you had it.

The first an array of three pointers to char .

The second is a pointer to an array of three char s.
(Read it as " *names is a char[3] ").

You can create such a pointer by taking the address of an array of three char s:

char name[3];
char (*names)[3] = &name;

or dynamically in the normal way:

char (*names)[3] = malloc(sizeof(*names)); /* or sizeof(char[3]), if you're fond of bugs */

or through the regular array-to-pointer conversion:

char stuff[2][3] = {};
char (*names)[3] = stuff; /* Same as &stuff[0], as normal. */ 
  • char *names[3] is an array of 3 char pointers.
  • char (*names)[3] is an array pointer (pointer to array) to an array of 3 characters char[3] .

So these two have fundamentally different meanings! Don't confuse them with each other.

If you wish to allocate an array of pointers , then you can do it as in either of these examples:

char** names = malloc(3 * sizeof(*names) );
char** names = malloc(sizeof(char*[3]));
char** names = calloc(3, sizeof(char*));

These are all equivalent (but calloc also sets all pointers to NULL). names will be a pointer to the first element in the array. It will be a pointer to a char* .

If you wish to allocate an array and point to the first element, simply do:

char* names = malloc(3 * sizeof(*names));

Alternatively, you can use the array pointer syntax and point to the array as whole:

char (*names)[3] = malloc(sizeof(*names));

and how to read this operators?

Let's take the second one as it is the more complex of the two:

char (*names)[3]; 

When you are looking at a complex definition like this, the best way to attack it is to start in the middle and work your way out. “Starting in the middle” means starting at the variable name, which is names .
“Working your way out” means looking to the right for the nearest item (nothing in this case; the right parenthesis stops you short), then looking to the left (a pointer denoted by the asterisk), then looking to the right (an array of 3), then looking to the left (char).
This right-left-right motion works with most declarations.

This means names is a pointer to an char array of size 3. This is very strange declaration but that is how it is read.

If I want to allocate memory for them dynamically how to do so?

Now that you know what the declaration means, memory allocation becomes easy:

char (*names)[3] = malloc(3 * sizeof(char));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM