Search code examples
cstrcat

Why does my C program segfault when I use strcat with dynamically allocated char arrays?


I need some help understanding the difference in behavior with strcat when passing in dynamically allocated char arrays versus char arrays declared with the index operator.

The following generates a segfault when executed:

char *destination = malloc(30 * sizeof(char));
destination = "Hello, ";
char *source = malloc(30 * sizeof(char));
source = "world!";
strcat(destination, source);

However this runs without error:

char destination[30] = "Hello, ";
char source[30] = "world!";
strcat(destination, source);

At first I thought the problem was a lack of a terminating null character when assigning the string to the pointer, however assigning "Hello, \0" and "world!\0" to the respective pointers still generates a segfault. What is my error in thinking?


Solution

  • This doesn't do what you think it does:

    char *destination = malloc(30 * sizeof(char));
    destination = "Hello, ";
    

    The first line initializes destination with the starting address of a block of allocated memory. The second line does not copy the string on the right into the string on the left, but instead overwrites the prior address value with the address of a string literal.

    This means the address of the allocated memory is lost and you have a memory leak. It also means that, since destination points to a string literal and string literals are read-only, that you can't modify the string it points to. Attempting to do so triggers undefined behavior in your code which in this case causes it to crash.

    To copy a string, you need to use the strcpy function:

    char *destination = malloc(30 * sizeof(char));
    strcpy(destination, "Hello, ");
    char *source = malloc(30 * sizeof(char));
    strcpy(source, "world!");