How can I return a character array from a function in C?
is that even possible? Let's say that I want to return an array of two characters
char arr[2];
arr[0] = 'c';
arr[1] = 'a';
from a function. What type do I even use for the function? Is my only choice to use pointers and void the function? So far I've tried having a char* function or a char[]. Apparently you can only have functions of char(*[]). The only reason I want to avoid using pointers is the fact that the function has to end when it encounters a "return something;" because the value of "something" is a character array (not a string!) that might change size depending on the values I pass into the function through the main function. Thanks to anyone who responds in advance.
You've got several options:
1) Allocate your array on the heap using malloc()
, and return a pointer to it. You'll also need to keep track of the length yourself:
void give_me_some_chars(char **arr, size_t *arr_len)
{
/* This function knows the array will be of length 2 */
char *result = malloc(2);
if (result) {
result[0] = 'c';
result[1] = 'a';
}
/* Set output parameters */
*arr = result;
*arr_len = 2;
}
void test(void)
{
char *ar;
size_t ar_len;
int i;
give_me_some_chars(&ar, &ar_len);
if (ar) {
printf("Array:\n");
for (i=0; i<ar_len; i++) {
printf(" [%d] = %c\n", i, ar[i]);
}
free(ar);
}
}
2) Allocate space for the array on the stack of the caller, and let the called function populate it:
#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0]))
/* Returns the number of items populated, or -1 if not enough space */
int give_me_some_chars(char *arr, int arr_len)
{
if (arr_len < 2)
return -1;
arr[0] = 'c';
arr[1] = 'a';
return 2;
}
void test(void)
{
char ar[2];
int num_items;
num_items = give_me_some_chars(ar, ARRAY_LEN(ar));
printf("Array:\n");
for (i=0; i<num_items; i++) {
printf(" [%d] = %c\n", i, ar[i]);
}
}
DO NOT TRY TO DO THIS
char* bad_bad_bad_bad(void)
{
char result[2]; /* This is allocated on the stack of this function
and is no longer valid after this function returns */
result[0] = 'c';
result[1] = 'a';
return result; /* BAD! */
}
void test(void)
{
char *arr = bad_bad_bad_bad();
/* arr is an invalid pointer! */
}
Since you have a predetermined size of you array you can in-fact return the array if you wrap it with a struct:
struct wrap
{
char a[2] ;
} ;
struct wrap Get( void )
{
struct wrap w = { 0 } ;
w.a[0] = 'c';
w.a[1] = 'a';
return w ;
}
You can return a pointer for the array from a function, however you can't return pointers to local arrays, the reference will be lost.
So you have 3 options:
-
Use a global variable:
char arr[2]; char * my_func(void){ arr[0] = 'c'; arr[1] = 'a'; return arr; }
-
Use dynamic allocation (the caller will have the responsibility to free the pointer after using it; make that clear in your documentation)
char * my_func(void){ char *arr; arr = malloc(2); arr[0] = 'c'; arr[1] = 'a'; return arr; }
-
Make the caller allocate the array and use it as a reference (my recommendation)
void my_func(char * arr){ arr[0] = 'c'; arr[1] = 'a'; }
If you really need the function to return the array, you can return the same reference as:
char * my_func(char * arr){
arr[0] = 'c';
arr[1] = 'a';
return arr;
}
You can pass the array to the function and let the function modify it, like this
void function(char *array)
{
array[0] = 'c';
array[1] = 'a';
}
and then
char array[2];
function(array);
printf("%c%c\n", array[0], array[1]);
If you want it as a return value, you should use dynamic memroy allocation,
char *function(void)
{
char *array;
array = malloc(2);
if (array == NULL)
return NULL;
array[0] = 'c';
array[1] = 'a';
return array;
}
then
char *array = function();
printf("%c%c\n", array[0], array[1]);
/* done using `array' so free it because you `malloc'ed it*/
free(array);
Important Note:
You should be aware of the fact that the array as filled above is not a string, so you can't for instance do this
printf("%s\n", array);
because the "%s"
expects a matching string to be passed, and in c an array is not a string unless it's last character is '\0'
, so for a 2 character string you need to allocate space for 3 characters and set the last one to '\0'
.