C言語で無限長文字列(ちょー簡易版)

C言語で無限長文字列を扱う関数を書いてみました。
普通、C言語でこういうことをやろうとすると、文字列用の構造体を作って、そこに今の文字列の長さと格納可能な長さ(確保済みバッファの長さ)を覚えておきます(たしかglibとかRubyのstring.cはそうなっていたと思います)。で、確保済みバッファが足りなくなったら、バッファのサイズを2倍とか1.5倍とかに拡張します(reallocの回数を減らすために、このようにしていたと思います)。
が、今回は面倒なので構造体を作らずに素のchar *を扱うことにします。なので、reallocは毎回発生します。効率が必要な用途には使わない方がよいでしょう。あー、C++だったらこんなこと考えなくてもいいのに。みたいな。

#include <stdlib.h>
#include <string.h>
#include <assert.h>

char *
str_init(char *s)
{
    assert(s != NULL);
    return strdup(s);
}

char *
str_append(char *dst, char *src)
{
    size_t dstlen;
    size_t srclen;

    assert(dst != NULL);
    assert(src != NULL);

    dstlen = strlen(dst);
    srclen = strlen(src);

    dst = realloc(dst, dstlen + srclen + 1);
    if (dst == NULL) {
        free(dst);
        return NULL;
    }
    strncat(dst, src, srclen);

    return dst;
}

#include <stdio.h>

int
main(int argc, char *argv[])
{
    char *s = str_init("foo");
    printf("<%s>\n", s);         /* => <foo> */

    s = str_append(s, "bar");
    if (s == NULL)
        goto err;
    printf("<%s>\n", s);         /* => <foobar> */

    s = str_append(s, "baz");
    if (s == NULL)
        goto err;
    printf("<%s>\n", s);         /* => <foobarbaz> */
    
    return 0;

  err:
    return 1;
}