You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:39:15