0

So imagine this fairly simple scenario. I have some function that does some manipulations and ends up returning an array of char pointers. For the sake of simplicity, let that function take no arguments:

#include <stdio.h>

char **func(void);

int main() {
    printf("%s\n", func()[0]);
    return 0;
}

char **func() {
    static char arr[3][10] = {"hi", "bye", "cry"};
    return arr;
}

I want to be able to access this array in my main() function. I make the array static in order to avoid returning the address to a local variable defined in the scope of func(). This code compiles, but with a warning:

warning: return from incompatible pointer type [-Wincompatible-pointer-types]

    return arr;

              ^

But what should I make the return argument then? A pointer to a char array? I thought that in C returning an array is bad practice.

Running this program results in an unhelpful segmentation fault.

So what am I doing incorrectly? Can I not return a pointer to an array of char pointers? Hence, a char **? Am I conflating array/pointer decay? How would I return an array of strings? Is there a way to return a string array without the use of the static keyword?

Edit: Surely you all are able to empathize with my confusion? It's not like the array-pointer decay functionality of C is trivial to reason about.

2
  • 2
    You do not have an array of char *. char** and char[][] is not the same data type. Why not declare your array as static char *arr[] = {"hi", "bye", "cry"}; Then you can return arr as in the original code. Commented Jan 21, 2017 at 17:37
  • 1
    What are you doing incorrectly? You want to return an array of char pointers, but you don't have an array of char pointers. (It's like wanting to return to a world in which global warming doesn't happen.) Commented Jan 21, 2017 at 17:44

2 Answers 2

2

In the statement return arr;, arr will decay to pointer to an array of 10 chars, i.e. of type char (*)[10] while return type of your function is char **. Both pointer types are incompatible.
You can change the type of arr in the declaration from array of arrays to array of pointers.

static char *arr[3] = {"hi", "bye", "cry"};   

or you can change the return type of the function to char (*)[10]

char (*func())[10] {...}
Sign up to request clarification or add additional context in comments.

4 Comments

This code does not quite do as you might expect. The declaration creates an array of 10 pointers to char. I rather suspect you were aiming for an array of pointers to 10 chars. That would be char (*arr[])[10]. For more on this fun topic see: cdecl.ridiculousfish.com
@PeterCamilleri; char (*arr[])[10] will declare arr as an array of pointers to an array of 10 chars. I intended to declare arr as an array of 3 pointers to char. By mistake I wrote 10 instead of 3.
OK, but in any event, even the three is not needed as the compiler can figure out how many elements are the the initializing constant. By not repeating this bit of information, it is just one less thing to get wrong. In some programming communities, this goes by the name DRY - Don't Repeat Yourself. Not common in "C" but still a useful concept when possible.
Well yes, until you need to change the number of strings and keep the count in sync, but yes, mostly harmless.
2

The array:

static char arr[3][10] = {"hi", "bye", "cry"}; 

is an array of arrays of 10 characters. This is NOT compatible with char **.

Try

static char *arr[] = {"hi", "bye", "cry"};

instead.

2 Comments

Thanks! Could I return a char* array without the use of static?
@KennethWorden No you cannot. If you return a pointer to a local variable, you have undefined behavior.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.