tez
tez

Reputation: 5300

char** vs char* c[] for accessing a string array

Why can't I point a char** to array of C strings??

int main(int argc, char *argv[]) {

    char* c1[] = {"Hey","Hello"};
    printf("%s",c1[1]);

} //works fine

vs

int main(int argc, char *argv[]) {

    char** c1 = {"Hey","Hello"};
    printf("%s",c1[1]);

} //error

Upvotes: 9

Views: 15475

Answers (5)

Arun
Arun

Reputation: 2092

"char **c1", tells compiler that it is a pointer to a pointer for type char, is scalar type (one value).

Initializing with a list of values only works for aggregate types.

Upvotes: 0

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

I think the confusion here stems from the belief that {"Hey","Hello"} is an array. It's not. It's not an object at all. It's just a special initializer syntax that can be used to initialize an array. You can't use it to initialise a char** because a char** is a pointer, not an array. It doesn't automatically create an array object that you can convert to a pointer.

Perhaps you were thinking of it like a [...] list in Python or a { ... } object in JavaScript. It's not like those at all. Those expressions actually create objects of that type and can be used anywhere in an expression that can take those objects. The syntax we're using in C++ is just an initialization syntax.

For example, you could do this:

const char* array[] = {"Hey","Hello"};
const char** p = array;

You, however, cannot do something silly like this:

std::cout << {"Hey", "Hello"}[1];

Here we have actually created the array object in which the pointers will be stored. Only then can we convert that array to a const char**.

Upvotes: 11

Mats Petersson
Mats Petersson

Reputation: 129364

int main(int argc, char *argv[]) {

    char** c1 = {"Hey","Hello"};
    printf("%s",c1[1]);

} //error

In the code above, you are trying to set a pointer to a pointer to a set of two strings. Where is the storage for the two pointers that contain the address of "Hey" and "Hello" respectively? Nowhere.

You could do:

 char *a = "Hey";
 char *b = "Hello";
 char *c[] = { a, b };     // This MAY not compile due to a and b not being compile time constants. 
 char **c1 = c;

(I've split it up into more individual variables than it actually needs, but I think it explains what is "wrong" with your code quite clearly).

Another example would be if we change the char * to int:

 const int a = 1;
 const int b = 2;

 int c[] = { a, b };

 int *c = { a, b };   // Doesn't work, there is nowhere to store a copy of a and b. 

It's the same thing, except with integers.

Upvotes: 1

BLUEPIXY
BLUEPIXY

Reputation: 40145

change to

char** c1 = (char *[]){"Hey","Hello"};

Upvotes: 4

md5
md5

Reputation: 23699

Why can't I point a char** to array of C strings?

As you said, c1 is an array. So you have to declare it as an array of pointers to char.

Since "Hey" and "Hello" are string litterals, each c1[i] string is pointing to an anonymous string. That's why you can use pointers to char instead of arrays of char.

To make an array of pointers to char, however, you can't use a char **.

Upvotes: 1

Related Questions