C语言创建动态二维数组时rows>4触发Segmentation Fault问题求助
动态二维数组行数超过4触发段错误的排查与修复
核心问题
你代码中创建指针数组时的内存分配计算错误是导致段错误的根本原因:
array = (int **)malloc(rows * sizeof(int));
这里你错误地使用了sizeof(int)来计算单个元素的大小,但array是int**类型,它的每个元素都是int*指针。在64位系统中,int通常是4字节,而int*是8字节——这意味着你实际分配的内存只有所需空间的一半。
当行数较少时,这种内存不足可能只是轻微越界,未破坏堆的关键结构,所以程序侥幸运行;但行数≥5时,越界写操作会破坏堆内存的管理信息,直接触发段错误。
修复方案
把sizeof(int)替换为sizeof(int*),更稳妥的写法是用sizeof(*array),这样即使后续修改指针类型,代码也能自动适配:
array = malloc(rows * sizeof(*array));
另外,你可以用calloc直接创建初始化为0的数组,省去手动循环赋值的步骤,同时增加内存分配失败的检查和内存释放逻辑,避免泄漏:
修正后的完整代码:
#include <stdio.h> #include <stdlib.h> int ** zeros(int rows, int cols) { int ** array; // 分配存储指针的数组,用sizeof(*array)确保类型匹配 array = malloc(rows * sizeof(*array)); if (!array) { perror("Failed to allocate row pointers"); return NULL; } for (int i = 0; i < rows; i++) { // calloc自动将内存初始化为0,无需手动赋值 array[i] = calloc(cols, sizeof(int)); if (!array[i]) { perror("Failed to allocate column data"); // 分配失败时回滚已分配的内存 for (int j = 0; j < i; j++) { free(array[j]); } free(array); return NULL; } } return array; } int main(void) { int rows = 5; int cols = 3; int ** zeroArray = zeros(rows, cols); if (!zeroArray) { return 1; } // 打印数组 for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { printf("%d ", zeroArray[r][c]); } printf("\n"); } // 释放内存,避免泄漏 for (int r = 0; r < rows; r++) { free(zeroArray[r]); } free(zeroArray); return 0; }
额外注意事项
- 内存分配检查:永远不要忽略
malloc/calloc的返回值,空指针访问会导致程序崩溃。 - 内存泄漏:动态分配的内存必须在使用完后释放,尤其是在分配过程中发生失败时,要回滚已分配的内存。
- 避免强制转换:C语言中
malloc的返回值是void*,可以直接赋值给任意指针类型,强制转换可能隐藏编译警告。
内容的提问来源于stack exchange,提问作者Bazalaylee
相关产品推荐
相关产品推荐

