Dynamic memory allocation + truncating a chain problem


I've been fooling around with malloc, realloc and free in order to write some basic functions to operate on C strings (char*). I've encountered this weird issue when erasing the last character from a string. I wrote a function with such a prototype:

int string_erase_end (char ** dst, size_t size);

It's supposed to shorten the "dst" string by one character. So far I have come up with this code:

int string_erase_end (char ** dst, size_t size)
    size_t s = strlen(*dst) - size;
    char * tmp = NULL;
    if (s < 0) return (-1);
    if (size == 0) return 0;
    tmp = (char*)malloc(s);
    if (tmp == NULL) return (-1);
    *dst = (char*)malloc(s+1);
    if (*dst == NULL) return (-1);
    *dst[s] = '\0';
    return 0;

In main(), when I truncate strings (yes, I called malloc on them previously), I get strange results. Depending on the number of characters I want to truncate, it either works OK, truncates a wrong number of characters or throws a segmentation fault.

I have no experience with dynamic memory allocation and have always used C++ and its std::string to do all such dirty work, but this time I need to make this work in C. I'd appreciate if someone helped me locate and correct my mistake(s) here. Thanks in advance.

The first strncpy() doesn't put a '\0' at the end of tmp.

Also, you could avoid a double copy: *dst = tmp;