1

I'm trying to create an array of char pointers in different ways, but only the first method works:

#include <stdio.h> 

int main(){

 char* a[] = {"hello"};
 // works

 char** b = {"hello"}; 
 // warning: incompatible pointer types initializing 
 // 'char **' with an expression of type 'char [6]' 

 char c[][] = {"hello"};  
 // error: array has incomplete element type 'char []'

 return 0;
}

What am I doing wrong?

3 Answers 3

2
  1. Since neither element is an array, the C compiler does not recognize the {"hello"} syntax as an array, which will cause the code to break. If you do char** b = a you can observe that the syntax does in fact work.
  2. When working with multidimensional arrays in C, every dimension except the first must be given a length, since the compiler cannot infer it. If you change it to char c[][6] = {"hello"} you can observe that it works.
Sign up to request clarification or add additional context in comments.

Comments

1

All of these are incorrect at some extent.

  • a initializes an array of 1 single pointer char*, pointing at the string literal "hello". But since we aren't allowed to modify string literals, this should have been written as const char* a[] = {"hello"};.
  • b attempts to set a pointer-to-a-char-pointer to point at a string literal, which is not valid C. A conforming compiler must give you a message saying that the code isn't correct.
  • c is nonsense syntax, we cannot declare arrays of arrays with no dimensions known. Only the left-most dimension can be left blank, for the compiler to set implicitly.

Comments

1
  1. This char* a[]; is an array of char*, aka array of char pointers.
  2. This char** b; is a pointer to char*, or, in other words, a pointer to pointer to char. The initializer {"hello"} is wrong because its type is "array of char*".
  3. This char c[][]; is an invalid declaration. You are declaring an array of arrays of char, but you don't specify the size of the subarray. You have to change it to something like char c[][N]; so that the sub-array has a known size, or even char c[M][N]; so that you know the entire size. Using the initializer here is OK, but note that it is interpreted as a completely different type than the first.

Correct initializations would be:

  1. char* a[] = {"hello"};, this will create an array a with one element pointing to some memory location chosen by the compiler where the "hello" string is stored.
  2. char** b = a; or char** b = &a[0];, this simply creates a pointer to pointer to char, so assigning a or &a[0] to it is the only reasonable thing here. There could be other applications, but it depends on the case.
  3. char c[][10] = {"hello"};, this will create an array c with one sub-array of size 10 holding the elements {'h', 'e', 'l', 'l', 'o', '\0', '\0', '\0', '\0', '\0'}.

1 Comment

This isn't entirely correct. For example 2, GCC treats {"hello"} as "hello" due to the typing of b, not an array containing "hello".