C: "zsh: abort" error

Alexander picture Alexander · Aug 29, 2017 · Viewed 7.8k times · Source

Here's my program:

#include <stdio.h>

char    *ft_strcat(char *dest, char *src)
{
    int i;
    int k;

    i = 0;
    k = 0;
    while (dest[i])
        i++;
    while (src[k])
    {
        dest[i + k] = src[k];
        //i++;
        k++;
    }
    dest[i + k] = '\0';
    return (dest);
}

int main(){
    //ft_strcat
    char str[] = "Hello, ";
    char str2[] = "World!";
    printf("%s", ft_strcat(str, str2));
    return 0;
}

It's implementing of strcat function. When I'm trying to copy "World!" to "Hello, " I have an error "zsh: abort". There's no problem when I'm trying to copy to "Hello ".

What can I do with this error? Why this comma causes this problem?

Answer

Sourav Ghosh picture Sourav Ghosh · Aug 29, 2017

When you define an array with empty dimension and initialize that with a brace-enclosed initializer list, the size of the array is determined by the supplied initializer list elements.

So, in your case, str and str2 are just long enough to hold the strings "Hello, " and "World!", respectively.

So, the problem here is, the destination buffer (passed as the first argument of ft_strcat()) has absolutely no space to hold the concatenated result. You're accessing out of bound memory, thus causing undefined behavior.

In the very first iteration of the while loop,

while (src[k])
    {
        dest[i + k] = src[k];
        //i++;
        k++;
    }

the index i+k points to out of bound memory for dest. No sooner than you try to use the index to access the memory location, you face UB.

You need to make sure, the destination has enough space left to hold the concatenated result. For that, you can have either of two approaches

  • Define a bigger array size statically and use that as destination. You can always check for the actual size vs. already used size easily in this case, as this is a character type array meant to be used as string (hint: sizeof vs strlen()).
  • You can make use of a pointer, use memory allocator function to allocate certain amount of memory and realloc() as needed.