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

首次编写栅栏密码函数遇栈溢出与-Wchar-subscripts警告求助

问题排查与修复

1. 解决-Wchar-subscripts警告

这个警告是因为你用char类型的变量i、j作为数组下标。char在多数编译器中是有符号类型,当变量值超出范围时会变为负数,作为数组下标会触发非法内存访问。解决方法:把循环变量i、j的类型从char改为int(更符合C语言数组下标的常规用法)。

2. 解决「stack smashing detected」栈溢出错误

这个错误由多处数组越界访问导致,具体问题和修复如下:

问题1:变量k未初始化

第一个填充railFence的循环里直接用k++,但k是未初始化的局部变量,初始值是随机垃圾值。这会导致随机访问stringa的内存位置,大概率超出字符串实际长度,触发越界。
修复:在使用k前初始化k = 0;,同时把k的类型改为int更安全。

问题2:填充railFence时未检查字符串长度

你的循环会尝试填充railFence的多个位置,但如果传入的stringa长度不够,k会持续递增,导致访问stringa的越界内存,破坏栈结构。
修复:赋值前检查stringa[k]是否为'\0',如果是就停止填充。

问题3:数组下标访问顺序颠倒

railFence定义为char railFence[3][56];,是3行56列(第一维是行,第二维是列)。但收集结果的循环里写了railFence[j][i],j范围是0到55,直接超出railFence第一维(仅3行)的范围,导致严重栈越界。
修复:将下标顺序改为railFence[i][j],与数组定义一致。

问题4:output数组可能越界

如果加密结果长度超过55(output[56]最后一位要放'\0'),会导致output越界。
修复:收集结果时检查k是否小于55,避免越界。

修复后的完整代码

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

void railFenceCipher(char *stringa){ 
    char railFence[3][56];
    char output[56];
    int k = 0;

    // 初始化栅栏数组为空格
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 56; j++) {
            railFence[i][j] = ' ';
        }
    }

    // 填充栅栏数组,同时检查字符串是否结束
    for (int i = 0; i < 3; i++) {
        for (int j = i; j < 56 && stringa[k] != '\0'; j += 4) {
            railFence[i][j] = stringa[k++];
        }
    }

    k = 0;
    // 收集加密结果,修正下标顺序并避免output越界
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 56 && k < 55; j++) {
            if (railFence[i][j] != ' ') {
                output[k++] = railFence[i][j];
            }
        }
    }

    output[k] = '\0';
    printf("Encrypted message: %s\n", output);
}

额外建议

  • 不要固定数组大小(比如56),可以通过strlen(stringa)计算输入长度,动态计算栅栏数组大小,或用malloc动态分配内存,让代码更通用。
  • 编译时除了-Wall,可以加上-Wextra和-g,后者方便用调试器(如gdb)跟踪内存访问问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:52:29