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

CS50替换问题集未分配内存引发段错误的原因咨询

为什么CS50 Substitution问题中必须为output分配内存?

嘿,我来给你把这个问题讲明白!首先得先搞懂CS50里的string到底是什么——它其实就是C语言里char*的一个别名而已,可不是那种自带内存管理的高级字符串类(比如C++的std::string)。说白了,string就是个指针,它本身不存储字符,只是指向一块内存区域的起始地址。

那如果不给output分配内存会咋样?要是你直接写string output;而不调用malloc,这个指针就是个野指针——它指向的内存地址完全是随机的,可能是程序里其他变量的内存,也可能是操作系统不让你碰的保护内存。这时候你去给output[i]赋值,就相当于在乱改不属于你的内存空间,操作系统一检测到这种非法访问,直接就给你抛出segmentation fault(段错误)了,这可不就崩了嘛!

再看你的需求:你要把输入字符串的每个字符替换后存到output里,那output必须要有一块足够大的、完全属于你的内存空间来存这些字符。malloc(strlen(input)+1)就是干这个的——它向操作系统申请了一块能容纳整个输入字符串(包括字符串末尾必须的'\0'终止符,所以要+1)的内存,然后把这块内存的起始地址赋值给output指针。这样你后续对output[i]的所有赋值操作,都是在你合法拥有的内存里进行,自然不会触发段错误了。

另外还要给你提个小bug:你代码里return output;之后写的free(output);完全是白写!因为函数执行到return就直接退出了,后面的代码根本不会运行,这就导致你申请的内存永远没被释放,会造成内存泄漏。正确的做法是:在调用cipher函数的地方,等你用完返回的output字符串之后,再调用free(output)来释放内存。

还有个小细节别忘了:malloc出来的内存是未初始化的,不会自动添加字符串终止符'\0',所以你在循环结束后得手动加一句output[strlen(input)] = '\0';,不然后续用字符串处理函数(比如printf)的时候,会因为找不到终止符而读越界,输出一堆乱码。

附上修正后的代码片段供你参考:

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

// 假设这是你实现的字符替换函数
char substitute(char c, string key);

string cipher(string input, string key) {
    // 申请足够容纳输入字符串+终止符的内存
    string output = malloc(strlen(input) + 1);
    if (output == NULL) { // 最好加个内存申请失败的判断,更严谨
        return NULL;
    }
    int len = strlen(input);
    for (int i = 0; i < len; i++) {
        if (isalpha(input[i])) {
            output[i] = substitute(input[i], key);
        } else {
            output[i] = input[i];
        }
    }
    // 手动添加字符串终止符
    output[len] = '\0';
    return output;
    // 这里的free永远执行不到,移到调用处去做
}

内容的提问来源于stack exchange,提问作者A.SALEH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:32:56