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".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.