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

为何本地IDE正常的代码在Exercism上触发Segmentation fault?

错误原因分析
  • 空指针访问触发段错误:Exercism的测试用例包含了传入NULL的场景,你的代码直接调用strlen(phrase),而strlen不允许传入空指针,会直接触发内存访问错误导致段崩溃。本地测试未覆盖该用例,因此未暴露问题。
  • 数组越界写入:你声明的temp数组大小为length,有效索引范围是0到length-1,但执行了temp[length] = '\0';的越界写入操作,属于未定义行为,不同环境下表现不同,Exercism的测试环境刚好触发了错误。
  • 变长数组的潜在风险:char temp[length];是C99标准的变长数组,栈空间有限,若测试用例传入超长字符串,可能导致栈溢出,也是段错误的潜在诱因。
代码改进方案

修复后的代码解决了上述问题,同时优化了逻辑效率:

#include "isogram.h"
#include <string.h>
#include <ctype.h>

bool is_isogram(const char phrase[]) {
    // 处理空指针输入
    if (phrase == NULL) {
        return true; // 按题目定义,空字符串视为isogram
    }

    // 用固定大小数组记录字母出现情况(仅26个小写字母)
    bool seen[26] = {false};
    const char* ptr = phrase;

    while (*ptr != '\0') {
        char c = tolower((unsigned char)*ptr);
        // 仅处理字母字符
        if (c >= 'a' && c <= 'z') {
            int index = c - 'a';
            if (seen[index]) {
                return false;
            }
            seen[index] = true;
        }
        ptr++;
    }

    return true;
}

// 本地测试用main函数,Exercism测试时不会调用
int main(void) {
    char phrase[] = "lumberjacks";
    if (is_isogram(phrase))
        printf("true");
    else
        printf("false");
    return 0;
}

改进点说明

  • 增加空指针判断:直接处理phrase == NULL的情况,避免调用strlen导致崩溃。
  • 替换变长数组:用固定大小的seen数组记录字母出现情况,既避免栈溢出,又将时间复杂度从O(n²)降至O(n)。
  • 消除越界风险:不再手动复制字符串并添加终止符,直接遍历原字符串,彻底规避数组越界问题。
  • 精准逻辑处理:只关注字母字符,自动跳过空格、连字符等非字母,完全符合isogram的定义(仅字母不重复)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 07:25:01