Search code examples
carraysvariable-length-array

How to fix this function so that it returns concatenation of two strings?


I am trying to write a custom function in C that will concatenate two strings. So far, I have come up with:

char *strcat406(char *str1, char *str2) {

    int str1length = 0;
    int str2length = 0;
    char newStr[str1length + str2length];
    int i;

    for (i = 0; i < str1[i] != '\0'; i++)
        str1length += 1;

    for (i = 0; i < str2[i] != '\0'; i++)
        str2length += 1;

    for (i = 0; i < str1[i] != '\0'; i++)
        newStr[i] = str1[i];

    for (i = i; i < str2[i] != '\0'; i++)
        newStr[i] = str2[i];

    return newStr;

}

I believe the code should work except for the line that reads return newStr;, Xcode is giving me an error that reads "address of stack memory associated with local variable (x) returned" and I think that is why I am not getting the string array printed in main like I want it to.

From my research, it seems like this is happening because the memory for the array returned is freed, and so I get a result I do not want, though I have not found a single answer on this site or even in the C documentation that has worked for me.

How can I change my function so that it returns the concatenation of two strings?


Solution

  • You must calculate the length of the resulting string, then allocate the memory for it, then copy it, then return it. You are now using a VLA. It is better to use malloc:

    char *strcat406(char *str1, char *str2) {
    
        int str1length = 0;
        int str2length = 0;
        char *newStr;  // note: length not known yet
        int i, j;
    
        for (i = 0; i < str1[i] != '\0'; i++)
            str1length += 1;
    
        for (i = 0; i < str2[i] != '\0'; i++)
            str2length += 1;
    
        newstr= malloc (str1length + str2length + 1);
    
        for (i = 0; str1[i] != '\0'; i++)
            newStr[i] = str1[i];
    
        for (j = 0 ;str2[j] != '\0'; j++)
            newStr[i+j] = str2[j];
    
        newstr[i+j]= '\0';
        return newStr;
    }
    

    There ara better ways to do this, but I stick to your approach. Don't forget to call free for the new string when you no longer need it.

    EDIT The better approach being:

    char *strcat406(char *str1, char *str2)
    {
        char *newStr= malloc(strlen(str1)+strlen(str2)+1);
        strcpy(newStr,str1);
        strcat(newStr,str2);
        return newStr;
    }