Reputation: 31
I'm trying to return an array of char pointers but compiler doesn't seem to like it.
char*[] get_multiple(int x) {
char *tmp[x];
int i;
for (i=0;i<x;i++)
tmp[i]=strdup("abc");
return tmp;
}
The compiler errors out with the following:
error: expected identifier or '(' before '[' token
on line 1
Any idea why the compiler doesn't like it and how to fix it?
(I know I can alternatively pass in a structure from the caller to store the return pointers, but I want to avoid doing that)
Upvotes: 1
Views: 117
Reputation: 95315
There are two types that you can't use as return types of functions:
What you need to do is declare a function that returns a pointer to pointer to char, or char **
. You must allocate enough memory to store the pointers to the strings — so, if you need 7 strings, you must allocate enough space to hold at least 7 char *
objects — and then you must allocate space for each of the 7 strings and assign these to the char *
you just allocated. Alternatively, if all of the strings in this array will have a maximum length, you can declare one contiguous block of memory and calculate the offset to each string.
To aid memory management, it might help to also create a free_multiple
function.
char **get_multiple(size_t max)
{
char **multiple = malloc(max * sizeof(*multiple));
for (size_t i = 0; i < max; i++)
multiple[i] = malloc(/* determine max length of string including null terminator */);
return multiple;
}
void free_multiple(char **multiple, size_t max)
{
for (size_t i = 0; i < max; i++)
free(multiple[i]); /* free individual strings */
free(multiple); /* free the container as well */
}
Upvotes: 1
Reputation: 4528
Allow me to add to @Lidong Guo's answer (quoted below)
You can't create a array by :
char * tmp[x]
,since x is known runtime!use
char **tmp = malloc(x*sizeof(char *));
instead
By looking at your code, I can see that you have misunderstood either what the array label tmp
actually represents or where tmp
is actually located.
When you allocate a variable (or an array of static size) in a function, it is stored on the stack, in your current stack frame. This stack frame is destroyed/freed as soon as the function returns and you should NOT be using/referencing that memory any more!!!
tmp
is a label that represents the memory address at which the tmp
array is located. This is on the stack so when your function returns it is no longer a valid pointer!
Forgive me if you already know this but judging by your terminology I suspect you might not.
In C you CAN NOT assign arrays to other arrays!
int array1[10], array2[10];
// ... Put some values into array 1 ...
array2 = array1; // ILLEGAL! DOES NOT COPY AN ARRAY
Similarly, if you return tmp
you are returning the address, NOT the array so if you are assigning it to another variable you should be copying it instead of assigning it!
Hence C does not allow you to return an array and you should be returning pointers instead.
But even when you return a pointer to tmp
you will be in trouble because of the way you are trying to allocate it (on the stack) so @Lidong Guo suggested that you allocate it on the Heap where it can live even after your function returns. However, this means that you will need to remember to free that memory!
So a rewrite of your function using @Lidong Guo's code would look like
char** get_multiple(int x) {
char **tmp = malloc(x * sizeof(char*));
int i;
for (i=0;i<x;i++)
tmp[i]=strdup("abc");
return tmp;
}
And a hypothetical main would use it like so:
int main()
{
char** multiple7;
multiple7 = get_multiple(7);
// Do some stuff on multiple 7
free(multiple7[3]);
// Do some more stuff ...
// Don't forget to free multiple7 array memory too
free(multiple7);
return 0;
}
Upvotes: 2
Reputation: 2857
You can't create a array by :char * tmp[x]
,since x is known runtime!
use char **tmp = malloc(x*sizeof(char *));
instead
Upvotes: 0