C语言自定义Strcat函数运行后XCode编译器输出异常汇编反馈咨询
问题分析与解决方案
首先,你的代码表面上能输出正确结果,但XCode给出的汇编反馈其实是栈内存越界触发的未定义行为的信号——只是你的程序运气好没立刻崩溃而已,本质上已经踩了C语言的红线。
为什么会出现这个问题?
你定义的char c[] = "abcdefg";是在栈上分配的数组,它的大小是固定的:字符串"abcdefg"有7个字符,加上末尾的'\0',总共占用8字节的栈空间。当你调用Strcat(c, d)时,d的内容"hijklmn"(含'\0'是8字节)会被追加到c的末尾,这时候需要的总空间是15字节,但c只有8字节的容量。
这种情况下,代码会往c数组的栈内存之外写数据,破坏了栈上的其他变量或者函数调用的返回地址等关键数据。XCode输出的汇编指令是系统栈保护机制或者异常处理的相关代码,用来应对这种非法内存访问的情况。
另外还要提一句:你的原Strcat函数最后没有给拼接后的字符串加'\0',这也是一个隐藏的未定义行为问题,虽然有时候能正常输出,但绝对不能忽略。
对应的解决方法
这里给你几种靠谱的修复方案,按需选择:
方案1:预分配足够大的目标数组
如果能提前确定需要的最大长度,直接给c分配足够的空间:
#include <stdio.h> void Strcat(char* a, char* b); int main(int argc, const char * argv[]) { // 预分配足够容纳两个字符串+结束符的空间 char c[20] = "abcdefg"; char d[] = "hijklmn"; Strcat(c, d); printf("%s\n",c); } void Strcat(char* a, char* b) { for(; *a!= '\0';a++); for(; *b != '\0';a++,b++) { *a = *b; } // 补上结束符,避免未定义行为 *a = '\0'; }
方案2:动态分配内存(更灵活)
如果无法提前确定字符串长度,用动态内存分配来保证空间足够:
#include <stdio.h> #include <stdlib.h> #include <string.h> char* Strcat(char* a, char* b); int main(int argc, const char * argv[]) { char *c = malloc(strlen("abcdefg") + 1); strcpy(c, "abcdefg"); char d[] = "hijklmn"; char *result = Strcat(c, d); if (result) { printf("%s\n", result); free(result); // 记得释放动态分配的内存 } return 0; } char* Strcat(char* a, char* b) { size_t len_a = strlen(a); size_t len_b = strlen(b); // 重新分配足够的内存:a的长度 + b的长度 + 1(结束符) char *new_str = realloc(a, len_a + len_b + 1); if (!new_str) { perror("realloc failed"); return NULL; } // 从a的末尾开始拷贝b的内容 strcpy(new_str + len_a, b); return new_str; }
这种方法适合字符串长度不确定的场景,既不会浪费空间,也能从根源避免越界。
方案3:在Strcat中添加长度检查(安全加固)
如果你想保留栈数组的使用方式,可以给Strcat函数添加目标数组的长度参数,提前检查是否有足够空间:
#include <stdio.h> #include <string.h> void Strcat(char* a, char* b, size_t max_len); int main(int argc, const char * argv[]) { char c[20] = "abcdefg"; char d[] = "hijklmn"; Strcat(c, d, sizeof(c)); printf("%s\n",c); } void Strcat(char* a, char* b, size_t max_len) { size_t len_a = strlen(a); size_t len_b = strlen(b); // 检查是否有足够空间容纳拼接后的字符串+结束符 if (len_a + len_b + 1 > max_len) { fprintf(stderr, "Error: not enough space to concatenate strings\n"); return; } strcpy(a + len_a, b); }
这种方式能在写入前拦截非法操作,避免破坏栈内存。
内容的提问来源于stack exchange,提问作者Wangsitu
相关产品推荐
相关产品推荐

