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

