-1

I trying to create a function to return a char *tab[] to a fill a char *tab1[]

#include <stdio.h>
#include <string.h>
char * fill(){
        char *tab[2];
        tab[0] = "text 1";
        tab[1] = "text 2";
        return tab;
}

int main(){
        char *tab1[2];
        tab1 = fill();
        return 0;
}

I tried to use strcpy, strncpy, return a char **, malloc. I only can copy an index per time, like tab1[0] = tab[0], but I need to return the complete array in one time.

I am using a recursive function to fill the *tab[] and to do this I need to concatenate some strings and var:

void fill(int n, char *x, char *y, char *z, char *tab[]){
        int i;
        char text[40];
        if(n == 1){
                strcpy(text, "text 1 ");
                strcat(text, x);
                strcat(text, " text 2 ");
                strcat(text, y);

                tab[0] = text;
        } else if(tab[n-1] == ""){
                strcpy(text, "text 1 ");
                strcat(text, x);
                strcat(text, " text 2 ");
                strcat(text, z);
                strcat(text, "\ntext 1 ");
                strcat(text, z);
                strcat(text, " text 2 ");
                strcat(text, y);

                tab[n-1] = text;
                if(n-1 > 1){
                        fill(n-1, x, z, y, tab);
                }
        }
}

And in the finish I need to return the tab[] to fill another tab in the main:

int main(){
            int n = 2;
            char *tab1[n];
            fill(n, "a", "b", "c", tab1);
            return 0;
    }
Rodrigo Vitor
  • 11
  • 1
  • 6
  • 1
    `tab[0] = text;` assigns the local `text` to `tab[0]`. This is valid only until the end of the function, after which `char text[40];` is not longer valid. The calling code can not use `tab[0]` without incurring _undefined behavior_ (UB). The calling code needs to provide memory for the concatenated strings or the function can allocate data. What do you want? – chux - Reinstate Monica Oct 01 '18 at 15:12
  • 1
    Do you actually need to return an array as in your first example, or to populate an array provided by the caller, as in your second example? They're kind of different. – Useless Oct 01 '18 at 15:12
  • I see you have attempted to code a recursive solution. This is not the best approach. Is recursion required? If so why that requirement? – chux - Reinstate Monica Oct 01 '18 at 15:15

2 Answers2

2

Firstly your table is local to the function and it does not exist outside the function scope.

Secondly table is not the pointer You cant use the table as the pointer and assign it in the main functions as you do.

char ** fill()
{
        char **tab = malloc(2 * sizeof (*tab));
        tab[0] = "text 1";
        tab[1] = "text 2";
        return tab;
}

int main()
{
        char **tab1;
        tab1 = fill();
        return 0;
}
0___________
  • 60,014
  • 4
  • 34
  • 74
0

You have a few problems in your existing code. Firstly, here:

        int n = 2;
        char *tab1[n]; /* here, the contents of tab1 are unspecified  */
        fill(n, "a", "b", "c", tab1); /* so here, you can't read them */

That is, when fill does

   } else if(tab[n-1] == ""){

it's assuming that tab[1] (on the first call) is something you can legally read. It isn't, because you never put anything in there.

You definitely can't assume it happens to point to the string literal "", and you also can't assume it points to any dereferenceable location (so you can't write !*tab[n-1] or !strcmp(tab[n-1], "") or whatever).

Fortunately from the way you wrote your code, you should never need to check this value, since you write exactly once to each entry. So, you can just remove that condition.

Next, you have another problem, in that the values you're assigning are pointers to a local char array with automatic lifetime: text. They all go out of scope when the function returns, and then it's illegal to dereference any of the items in tab1. Changing the assignments to eg.

tab[n-1] = strdup(text);

will fix that, but be aware the caller is then responsible for freeing each element.

Useless
  • 64,155
  • 6
  • 88
  • 132