Search code examples
cstringstrcat

Confusion in "strcat function in C assumes the destination string is large enough to hold contents of source string and its own."


So I read that strcat function is to be used carefully as the destination string should be large enough to hold contents of its own and source string. And it was true for the following program that I wrote:

#include <stdio.h>
#include <string.h>

int main(){
    char *src, *dest;
    printf("Enter Source String : ");
    fgets(src, 10, stdin);
    printf("Enter destination String : ");
    fgets(dest, 20, stdin);
    strcat(dest, src);
    printf("Concatenated string is %s", dest);
    return 0;
}

But not true for the one that I wrote here:

#include <stdio.h>
#include <string.h>

int main(){
    char src[11] = "Hello ABC";
    char dest[15] = "Hello DEFGIJK";
    strcat(dest, src);
    printf("concatenated string %s", dest);
    getchar();
    return 0;
}

This program ends up adding both without considering that destination string is not large enough. Why is it so?


Solution

  • The strcat() function is indeed to be used carefully because it doesn't protect you from anything. If the source string isn't NULL-terminated, the destination string isn't NULL-terminated, or the destination string doesn't have enough space, strcat will still copy data. Therefore, it is easy to overwrite data you didn't mean to overwrite. It is your responsibility to make sure you have enough space. Using strncat() instead of strcat will also give you some extra safety.

    Edit Here's an example:

    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        char s1[16] = {0};
        char s2[16] = {0};
        strcpy(s2, "0123456789abcdefOOPS WAY TOO LONG");
          /* ^^^ purposefully copy too much data into s2 */
        printf("-%s-\n",s1);
        return 0;
    }
    

    I never assigned to s1, so the output should ideally be --. However, because of how the compiler happened to arrange s1 and s2 in memory, the output I actually got was -OOPS WAY TOO LONG-. The strcpy(s2,...) overwrote the contents of s1 as well.

    On gcc, -Wall or -Wstringop-overflow will help you detect situations like this one, where the compiler knows the size of the source string. However, in general, the compiler can't know how big your data will be. Therefore, you have to write code that makes sure you don't copy more than you have room for.