自定义字符串拼接函数运行异常,百思不得其解,烦请高人指教

自定义字符串拼接函数运行错误,百思不得其解,烦请高人指教。
C/C++ code

#include <stdio.h>

char* strcat(char *s1, const char *s2)
{
    char *head=s1;
    while(*s1++);
    *s1--;
    while(*s1++=*s2++);
    return head;
}

int main()
{
    // 测试串 1
    //char s1[]="ABCD";
    //char s2[]="EFGH";
    // 测试串 2
    char s1[]="ABCDABCDABCDABCDABCDA";//21
    char s2[]="EFGHEFGHEFGHEFGHEFGHEF";//22
    // 测试串 3
    //char s1[]="A";//1
    //char s2[]="BCDABCDABCDABCDABCDAEFGHEFGHEFGHEFGHEFGHEF";//42
    
    // 测试串 4
    //char s1[]="A";
    //char s2[]="EFGHEFGHEFGHE";//16

    char *out = strcat(s1,s2);
    printf("%s\n",out);
}



以下代码为字符串拼接函数,具体运行测试情况如下:
对于 “测试串 1”-->正常;
对于 “测试串 2”-->正常,但无论 s1 或 s2 增加 1 个字符,程序就进入无限循环;
对于 “测试串 3”-->运行错误,尽管 {“测试串 2”长度==“测试串 3”长度]};
当 逐渐减少“测试串 3”中 s2 的字符数量,使得 “测试串 3”长度==16时(即“测试串 4”),程序再次进入无限循环,直到 “测试串 3”长度<16时,程序恢复正常 ;
 
为什么会出现这种情况?百思不得其解,烦请高人指教。

------解决方案--------------------
C函数

原型
  extern char *strcat(char *dest,char *src);
用法
  #include <string.h>
  在C++中,则存在于<cstring>头文件中。
功能
  把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。
说明
  src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串
  返回指向dest的指针。
------解决方案--------------------
s1的空间总是要大于等于s2才能容纳,可以这样写:
 char s1[81]="ABCDABCDABCDABCDABCDA";
------解决方案--------------------
目测是这个问题
探讨

s1的空间总是要大于等于s2才能容纳,可以这样写:
char s1[81]="ABCDABCDABCDABCDABCDA";

------解决方案--------------------
C/C++ code

char out[1024];//1024,当然可以是其它值,定死了能拼接的字节长度