somerandomusername
somerandomusername

Reputation: 2023

Cpp pointers and arrays

could you please help me understand this.

I have function that needs "char ***argv";

As far as I understand it's : pointer to pointer to array of char pointers.

something like this: "char *arr[]" ?

char xx1 = '1';
char xx2 = '2';
char *argv[] = {&xx1,&xx2};

Then I call my function with gtk_init (&argc, &argv);

And get error:

main.cpp:43:31: error: cannot convert ‘char* (*)[2]’ to ‘char***’ for argument ‘2’ to ‘void gtk_init(int*, char***)’

Thank you for any help.

Upvotes: 2

Views: 750

Answers (1)

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

A char*** is a "pointer to pointer to pointer to char". No arrays involved at all. Your argv is an "array of 2 pointer to char". The name of your array, argv, will decay to a pointer to its first element in certain circumstances - this pointer will have type char**, or "pointer to pointer to char".

When you do &argv, you get a char* (*)[2], or a "pointer to array of 2 pointer to char". Which is not what you want. That's because you're taking the address of an array, not of a pointer.

Also, you're going to have a problem with the fact that you're pointers in argv are just pointing at single chars, not at null-terminated strings. gtk_init will almost certainly be expecting null-terminated strings.

So what you can you do? Try this:

char xx1[] = "1"; // Now these are null-terminated strings
char xx2[] = "2";
char* argv[] = {xx1, xx2};
char** argvp = argv; // Use the fact that the array will decay
gtk_init(&argc, &argv); // &argv will now be a char***

The reason for using arrays for the strings is because we need the chars to be non-const, but a char* str = "hello"; style declaration is deprecated - it must be const char*. However, by using arrays, the contents of the string literal are copied into our array, so we can freely make it non-const.

gtk_init really just expects you to pass the argc and argv parameters of your main function to it like so:

int main(int argc, char* argv[])
{
  gtk_init(&argc, &argv);
  // ...
}

You may now ask "But why is &argv now allowed? argv is the same type as in the question! Why don't we get a pointer to array again?" Actually, argv is not the same type, despite how much it looks like it is. When you define a function that takes an array argument, it actually gets transformed to a pointer. So the definition of main is equivalent to:

int main(int argc, char** argv);

So when we do &argv, we're totally fine, because it gives us a char***.

As @OmnipotentEntity says in the comments - you'd better have a good excuse for not passing the parameters of main to gtk_init.

Upvotes: 4

Related Questions