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

使用strcat()循环拼接多字符串触发段错误,求解决方法及替代方案

解决strcat触发Segmentation Fault的问题及替代实现方法

错误原因

  • 你初始化的name = ""是只读字符串常量,存储在程序的只读数据段,strcat会尝试向该地址写入数据,直接触发内存访问权限错误,导致段错误。
  • 即便目标是可写内存,若未预留足够空间容纳拼接后的内容,也会引发缓冲区溢出,导致未定义行为(包括段错误)。

修复方案(基于strcat)

方案1:提前计算总长度并分配足够内存

先统计所有要拼接的字符串总长度,一次性分配足够的可写内存,再进行拼接:

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    string delimiters[] = {",", "."};
    int delimiter_count = sizeof(delimiters)/sizeof(delimiters[0]); // 自动计算元素数量

    // 计算所有分隔符的总长度
    size_t total_len = 0;
    for(int i = 0; i < delimiter_count; i++)
    {
        total_len += strlen(delimiters[i]);
    }

    // 分配内存,+1用于存储字符串终止符'\0'
    string name = malloc(total_len + 1);
    if (name == NULL)
    {
        fprintf(stderr, "内存分配失败\n");
        return 1;
    }
    name[0] = '\0'; // 初始化为空字符串

    // 循环拼接
    for(int i = 0; i < delimiter_count; i++)
    {
        strcat(name, delimiters[i]);
    }

    printf("拼接结果:%s\n", name);
    free(name); // 释放动态分配的内存
    return 0;
}

方案2:动态扩展内存(适用于未知总长度的场景)

每次拼接前重新分配内存,确保有足够空间:

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    string delimiters[] = {",", "."};
    int delimiter_count = sizeof(delimiters)/sizeof(delimiters[0]);

    // 初始分配1字节存储空字符串的终止符
    string name = malloc(1);
    if (name == NULL)
    {
        fprintf(stderr, "内存分配失败\n");
        return 1;
    }
    name[0] = '\0';

    for(int i = 0; i < delimiter_count; i++)
    {
        size_t current_len = strlen(name);
        size_t add_len = strlen(delimiters[i]);

        // 重新分配内存,确保能容纳现有内容+新内容+终止符
        string temp = realloc(name, current_len + add_len + 1);
        if (temp == NULL)
        {
            fprintf(stderr, "内存分配失败\n");
            free(name); // 避免内存泄漏
            return 1;
        }
        name = temp;
        strcat(name, delimiters[i]);
    }

    printf("拼接结果:%s\n", name);
    free(name);
    return 0;
}

其他实现方法

使用snprintf更安全可控

snprintf可以精确控制写入的字符数,避免缓冲区溢出,适合字符串拼接场景:

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
    string delimiters[] = {",", "."};
    int delimiter_count = sizeof(delimiters)/sizeof(delimiters[0]);

    size_t total_len = 0;
    for(int i = 0; i < delimiter_count; i++)
    {
        total_len += strlen(delimiters[i]);
    }

    string name = malloc(total_len + 1);
    if (name == NULL)
    {
        fprintf(stderr, "内存分配失败\n");
        return 1;
    }

    size_t write_pos = 0;
    for(int i = 0; i < delimiter_count; i++)
    {
        // 从当前位置写入字符串,确保不越界
        write_pos += snprintf(name + write_pos, total_len - write_pos + 1, "%s", delimiters[i]);
    }

    printf("拼接结果:%s\n", name);
    free(name);
    return 0;
}

关键注意事项

  • 字符串常量(如""、",")存储在只读内存,不能作为strcat的目标参数,必须使用栈上数组或堆上动态分配的可写内存。
  • 动态分配内存后,必须检查malloc/realloc的返回值,避免空指针访问。
  • 用完动态分配的内存后要调用free,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Salai Saidhanyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:33:16