为何自行实现strcat()函数时源字符串输出结果异常?
问题原因分析及解决办法
我来帮你拆解这个问题,核心原因是栈内存溢出导致的相邻变量覆盖,咱们一步步说清楚:
为什么source字符串会被修改?
你在main里声明的target和source都是局部数组,它们会被分配在栈内存中,而且通常是相邻存储的。
char target[] = "ram";编译器会自动分配刚好能容纳这个字符串的空间:4字节('r'、'a'、'm'、'\0'),完全没有多余空间用来追加其他字符。char source[] = "shyam";占6字节('s'、'h'、'y'、'a'、'm'、'\0')。
当你调用fun函数往target后面追加source时,target的空间根本不够容纳追加后的内容(需要至少3+5+1=9字节),所以写入操作会越界,直接覆盖到相邻的source数组的内存区域。
具体来看覆盖过程:
- 初始
x = strlen(target) = 3,开始把source的字符依次写入target[3]、target[4]... target[4]已经超出了target数组的合法范围,而这个地址正好是source数组的起始位置(source[0]),于是source[0]的's'被覆盖成了'h';- 后续的写入继续覆盖
source的后续元素,最终source数组的内容被改成了'h'、'y'、'a'、'm'、'\0'、'\0',所以最后printf("%s", source)会输出hyam。
解决办法
解决这个问题的关键是给target分配足够的空间,避免越界写入:
方法1:显式指定足够大的数组大小
修改main里的target声明,指定一个足够容纳最终字符串的大小,比如:
char target[20] = "ram"; // 20字节足够容纳"ram"+"shyam"和结束符
方法2:动态分配内存(更灵活)
如果不确定最终字符串的长度,可以用malloc/realloc动态分配内存,记得用完后释放:
#include <stdio.h> #include <string.h> #include <stdlib.h> char *fun(char *target, const char *source) { printf("%s\n", source); size_t target_len = strlen(target); size_t source_len = strlen(source); // 重新分配足够的内存 char *new_target = realloc(target, target_len + source_len + 1); if (new_target == NULL) { perror("realloc failed"); return target; // 分配失败返回原指针 } target = new_target; char *ptr = target + target_len; while (*source != '\0') { *ptr++ = *source++; } *ptr = '\0'; return target; } int main() { char *target = strdup("ram"); // 动态分配内存复制字符串 char source[] = "shyam"; target = fun(target, source); printf("%s\n", target); printf("%s", source); free(target); // 释放动态分配的内存 return 0; }
额外注意点
- C语言不会自动检查数组越界,所以写代码时一定要确保目标数组有足够的空间,否则会导致不可预测的行为(比如内存覆盖、程序崩溃)。
- 标准库的
strcat同样要求目标数组必须有足够的空间容纳追加后的字符串,否则行为未定义,这也是你的代码出现问题的根本原因。
内容的提问来源于stack exchange,提问作者Ankit Bhardwaj
相关产品推荐
相关产品推荐

