Boyang
Boyang

Reputation: 2566

Initialize char**

I'm very new to C++. I'm trying to call a function that takes in char**:

bool func(char** a) {
    //blablabla
}

So it takes in an array of c-strings. I need to create a char**, but nothing works.

char** a = char[255][255]; // error: type name is not allowed

char** a = new char[255][255]; // error: a value of type "char (*)[255]" cannot be used to initialize an entity of type "char **"

char a[][] = {"banana", "apple"};
char** b = &a; // error: a value of type "<error-type> (*)[2]" cannot be used to initialize an entity of type "char **"

At the end I need to do:

char* a[] = {"banana", "apple"};

Why the first few didn't work and why the last one worked?

Thanks in advance.

Upvotes: 17

Views: 54462

Answers (5)

Tarık
Tarık

Reputation: 129

char ** is a scalar type, you have to cast to (char *[]), try this :

char **temp = (char *[]){"abc", "def","fg"};

Upvotes: 0

Shoe
Shoe

Reputation: 76240

There's a lot wrong in your code.

char** a = char[255][255]; // error: type name is not allowed

First of all this is not even valid C++ (or C for that matter). Maybe you meant:

char a[255][255];

In any case always remember that the type of a bi-dimensional dynamically allocated array is not ** but (*)[N] which is very different.

char** a = new char[255][255]; // error: a value of type "char (*)[255]" cannot be used to initialize an entity of type "char **"

The error message you provide in the comment explains exactly what I said earlier.

char a[][] = {"banana", "apple"};

In the above code the correct type of the variable a should be char* a[]. Again, arrays and pointer (for what the type is concerned) are very different things. A char array may decay to pointer (if NULL terminated), but for the rest, except with explicit casts, you can't use pointers and arrays like you are doing.

The last one worked because, like I said earlier, char* [] is the correct type for an array of C-strings.

Anyway, if you just doing homework, it is ok to learn this things. But in future development using C++: try not to use "features" that start with C-, like C-strings, C-arrays, etc. C++'s standard library gives you std::string, std::array, std::vector and such for free.

If you really need to allocate dynamic memory (with new and delete, or new[] and delete[]) please use smart pointers, like std::shared_ptr or std::unique_ptr.

Upvotes: 12

user823738
user823738

Reputation: 17521

char**

is ambiguous - it can mean:

  1. pointer to pointer
  2. array of c-strings - experienced programmer would write char* arr[] instead

In the first case it is quite simple:

char* niceString = GetNiceString();
func(&niceString);

however in the second case it is slightly more complex. The function will not know the length of the array so you need to end it explicitly with a NULL, just like for example environ is:

char* a[3] = { "One", "Two", NULL }; /* note that this is possibly  dangerous
because you assign const char* (READ-ONLY) to char* (WRITABLE) */
func(a); // char*[] gets downgraded to char** implicitly

Upvotes: 2

Jack
Jack

Reputation: 133567

You say you are working in C++. Then you can easily ignore const char* and char** and focus about what you can use:

#include <string>
#include <vector>

std::vector<std::string> arrayOfStrings;
arrayOfStrings.push_back("foo");

bool func(const std::vector<std::string>>& a) {
  ..
}

If you know the size at compile time you can even use std::array:

std::array<255, std::string> fixedArrayOfStrings

EDIT: since you need to build an array of C strings in any case you can easily do it starting from the vector:

const char **arrayOfCstrings = new const char*[vector.size()];

for (int i = 0; i < vector.size(); ++i)
  arrayOfCstrings[i] = vector[i].c_str();

func(arrayOfCstrings);

delete [] arrayOfCstrings;

Upvotes: 7

dare
dare

Reputation: 662

so char** a = char[255][255]; it's weird to C and C++ and if you want a static 2d array just

char a[255][255];

Upvotes: 0

Related Questions