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

C语言指针数组值莫名自变问题求助:动态二维数组赋值异常

问题分析与修复

你的代码里有两个核心的内存分配错误,正是这些错误导致了段错误和已初始化的值莫名改变的问题,我来一步步给你拆解:

错误1:二级指针的内存分配大小错误

你定义的visited是bool**类型(指向bool指针的指针),但在第一次分配内存时:

if ((visited = malloc(Limit * sizeof(bool))) == NULL) return;

这里你用了sizeof(bool),但实际上应该分配的是指针的大小,也就是sizeof(bool*)。因为visited数组里的每个元素都是一个bool*指针,而不是单个bool值。

在64位系统中,指针大小是8字节,bool通常是1字节,这意味着你实际分配的内存只有需要的1/8,当Limit较大时,必然会出现内存越界,后续的操作会覆盖其他内存区域的数据,导致之前初始化的visited[0][0]被意外修改。

错误2:一维数组的内存分配缺少类型大小

在给每个visited[i]分配内存时:

if ((visited[i] = malloc(Limit)) == NULL) return;

这里malloc(Limit)只分配了Limit个字节,但你需要的是Limit个bool类型的空间。虽然多数平台上bool是1字节,但规范的写法应该是malloc(Limit * sizeof(bool)),这样能避免不同平台上的类型大小差异问题,也让代码更清晰。

额外小问题:main函数的错误返回值

main函数是int类型,错误时应该返回非0值(比如return 1;),而不是直接return;,这会被默认当作return 0;,无法正确标识程序出错。

修正后的代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> // 别忘了引入stdbool.h,否则bool类型可能不被识别

int Limit = 0;
int Bomb = 0;
int getsum(int num) {
    int result = 0;
    while (num) {
        result = result + num % 10;
        num /= 10;
    }
    return result;
}
int calc_limit(int x) {
    while ((getsum(x)) < Bomb) x++;
    return x;
}
int main(int argc, char **argv) {
    if (argc < 2) { // 增加参数检查,避免空指针访问
        printf("请传入Bomb参数\n");
        return 1;
    }
    Bomb = atoi(argv[1]);
    Limit = calc_limit(0);
    int i = 0;
    int j = 0;
    bool **visited;
    // 修正:分配Limit个bool*指针的空间
    if ((visited = malloc(Limit * sizeof(bool*))) == NULL) {
        perror("malloc failed");
        return 1;
    }
    while (i < Limit) {
        // 修正:分配Limit个bool的空间
        if ((visited[i] = malloc(Limit * sizeof(bool))) == NULL) {
            perror("malloc failed");
            // 内存分配失败时要释放已分配的内存,避免内存泄漏
            for (int k = 0; k < i; k++) {
                free(visited[k]);
            }
            free(visited);
            return 1;
        }
        while (j < Limit) {
            visited[i][j] = false;
            j++;
        }
        j = 0;
        i++;
    }
    printf("%d\n", visited[0][0]); // 现在输出应该是0了

    // 用完后别忘了释放内存
    for (int k = 0; k < Limit; k++) {
        free(visited[k]);
    }
    free(visited);
    return 0;
}

为什么之前会出现visited[0][0]值变化的情况?

因为第一次malloc分配的内存不足,当你循环到i=3时,visited[3]的赋值已经越界访问了visited数组的内存区域,覆盖了visited[0]指针指向的内存地址或者该地址附近的数据,导致后续访问visited[0][0]时,读取的是被意外覆盖的垃圾值(比如你看到的176)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:18:36