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

求解哈佛CS50 Caesar习题时遭遇Segmentation fault (core dumped)错误

解决CS50 Caesar习题中的Segmentation Fault问题

核心问题分析

  • 未校验命令行参数:程序直接读取argv[1],如果运行时未传入密钥参数,会访问非法内存地址触发段错误。
  • 密文字符串未分配有效内存:string cipher = "";指向的是只读的空字符串常量,无法通过cipher[i]修改其内容,这是引发段错误的直接原因。
  • rotate函数逻辑漏洞:未区分大小写字母,非字母字符(空格、数字等)会被错误偏移,且大写字母超出范围的情况未处理。

修复后的完整代码

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

char rotate(char c, int n);

int main(int argc, string argv[])
{
    // 检查命令行参数数量是否合法
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // 校验密钥是否为纯数字(符合CS50习题要求)
    for (int i = 0; argv[1][i] != '\0'; i++)
    {
        if (!isdigit(argv[1][i]))
        {
            printf("Usage: ./caesar key\n");
            return 1;
        }
    }

    string plaintext = get_string("plaintext: ");
    int key = atoi(argv[1]);
    int length = strlen(plaintext);
    // 为密文动态分配内存,预留字符串终止符位置
    string cipher = malloc(length + 1);
    if (cipher == NULL)
    {
        printf("Memory allocation failed\n");
        return 1;
    }

    for (int i = 0; i < length; i++)
    {
        cipher[i] = rotate(plaintext[i], key);
    }
    // 添加字符串终止符,保证printf能正确识别
    cipher[length] = '\0';

    printf("ciphertext: %s\n", cipher);
    // 释放动态分配的内存,避免内存泄漏
    free(cipher);
    return 0;
}

char rotate(char c, int n)
{
    // 非字母字符直接返回,不做偏移
    if (!isalpha(c))
    {
        return c;
    }

    // 区分大小写,以对应字母为基准计算循环偏移
    char base = isupper(c) ? 'A' : 'a';
    return (c - base + n) % 26 + base;
}

关键修复点说明

  • 命令行参数校验:先判断参数数量,再验证密钥是否为纯数字,符合习题的输入规范,避免非法内存访问。
  • 动态内存管理:用malloc为密文字符串分配足够内存,使用完成后用free释放,既解决了段错误,也避免内存泄漏。
  • rotate函数优化:用isalpha和isupper区分字符类型,通过模26运算实现循环移位,逻辑简洁且覆盖所有合法输入场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:10:34