user983223
user983223

Reputation: 1154

returning character array from function

I'm trying to return a char array from a function. According to everything I have read I understand I cannot return the array itself because arrays are second class citizens. But from what I understand I can create a pointer to it and make it static. I have tried both and am failing to compile. Any ideas why?

int main ()
{
  char *hold_array[] = get_array ();                                                              
  return 0;
}

char *get_array (void)
{
   static char *array[] = {"test1", "test2"};
   return (array);
}

Upvotes: 0

Views: 156

Answers (4)

Yu Hao
Yu Hao

Reputation: 122373

compile error because of type mismatch. @JustinPeel points out that const is needed too.

int main(void)
{
    char **hold_array = get_array ();
    return 0;
}

char **get_array(void)
{
     static const char *array[] = {"test1", "test2"};
     return (array);
}

Upvotes: 2

user2513931
user2513931

Reputation:

The *hold_array[] is an array of pointers. The function get_array returns a single pointer, albeit that the returned pointer is a pointer to an array of char * pointers. However, you cannot declare *hold_array[] as an array of pointers without any dimension. The compiler has no idea how much space to allocate for it. It doesn't know how many pointers you'll need.

You can declare it as **hold_array. This is a single pointer which points to an array of pointers. I know it sounds the same, but it isn't exactly. In the case of *hold_array[] you are allocating multiple pointers and therefore need a dimension. In the case of **hold_array you are allocating one pointer which points to an array of pointers. In your initializer static char *array[] the compiler sees you need two pointers and internally dimensions it for you as *array[2].

Therefore in main() you are asking the compiler to create an array of unknown dimension which consists of char * pointers. The function get_array returns the address of an array of pointers, but not the individual pointers within the array. Remember that array[0] is a pointer to the string "test1" and array[1] is a pointer to the string "test2". The strings themselves are character arrays with a 0 byte at the end.

Another way to think of it is:

char *test1 = "test1";
char *test2 = "test2";

char *array[2];
char **hold_array;

array[0] = test1;
array[1] = test2;

hold_array = array;

printf("\n%s = %s", hold_array[0], array[0]);  //print the same string

Therefore, when you return array the compiler assumes you mean the array itself since you haven't otherwise specified a member of the array. So only the address of array itself is returned. This is identical to **hold_array. Which means hold_array = array. **hold_array is a single pointer which points to an array of pointers. array[2] is an array of pointers which allocated space for 2 pointers.

Upvotes: 1

Nobilis
Nobilis

Reputation: 7448

For what you want to do it is best to allocate the array dynamically using malloc and then return a pointer to the allocated memory.

E.g.:

char* char_array_ptr = malloc(sizeof(char) * size_of_array);

Do note that sizeof(char) is redundant since the char type is guaranteed to be 1 by the standard, though you will need sizeof for other types.

You function should have a signature similar to char* return_array() and you should return the pointer to the allocated memory at the end of the function - return array_ptr;

All in all we would have something like:

char* allocate_array()
{
    char* ptr = malloc(20); /* size here will be 20 */

    strcpy(ptr, "Just a normal string."); /* copy string to that pointer */

    return ptr; /* return pointer for further use */
}

Don't forget to free the memory allocated with malloc once you're done using it.

Upvotes: 1

Ed Heal
Ed Heal

Reputation: 59987

Try changing

char *hold_array[] = get_array ();

to

char **hold_array = get_array ();

Or (better still IHMO) to use malloc.

Upvotes: 1

Related Questions