Я подозреваю, что это потому, что реализация перезаписывает нулевой байт в конце:
Start: a = {h,i,\0}
src^ vdst
next: a = {h,i,h}
src^ vdst
next: a = {h,i,h,i}
src^ vdst
next: a = {h,i,h,i,h}
...
Поскольку вы перезаписали нулевой терминатор, ваша исходная строка никогда не закончится, и метод продолжит копирование до тех пор, пока не попытается получить доступ к памяти, которой он не должен, и segfaults.