C语言动态二维数组初始化出现Access Violation写入位置错误求助
问题分析与解决方案
你遇到的问题核心在于对二维数组的内存分配方式理解有误——你现在用malloc(vertexCount*vertexCount*(sizeof(int)))分配的是一块连续的int类型内存,但却把它赋值给了int**类型的变量,这会导致访问内存时的地址解析错误,直接触发访问违规。
为什么会出错?
int**本质是「指向指针的指针」,它要求内存布局是:先有一个指针数组(每个元素都是指向int数组的指针),然后每个指针再指向一行的int数据。但你现在分配的是一整块连续的int内存,没有中间的指针数组。当你尝试访问fwdistance[i][j]时,程序会先读取fwdistance[i]的值(把它当成一个指针地址),然后再偏移j个int的位置去访问内存——但这个值本身是你后续要存储的int数据(初始是垃圾值),不是合法的内存地址,自然会触发访问违规。
而你之前Dijkstra的代码没问题,是因为int*类型直接对应一维的int数组,分配方式是完全匹配的。
两种可行的修复方案
方案1:分配真正的二维指针数组(非连续内存)
先分配存储指针的数组,再给每个指针分配一行的内存,这样就能符合int**的内存布局要求:
// 先分配指针数组,每个元素是指向int数组的指针 int** fwdistance = malloc(vertexCount * sizeof(int*)); int** fwnext = malloc(vertexCount * sizeof(int*)); // 给每个指针分配一行的内存空间 for (int i = 0; i < vertexCount; i++) { fwdistance[i] = malloc(vertexCount * sizeof(int)); fwnext[i] = malloc(vertexCount * sizeof(int)); } // 现在可以正常初始化二维数组了 for (int i = 0; i < vertexCount; i++) { for (int j = 0; j < vertexCount; j++) { fwdistance[i][j] = INT_MAX; fwnext[i][j] = -1; } }
⚠️ 注意:后续释放内存时要分层释放,先释放每一行的内存,再释放指针数组:
for (int i = 0; i < vertexCount; i++) { free(fwdistance[i]); free(fwnext[i]); } free(fwdistance); free(fwnext);
方案2:用一维数组模拟二维数组(连续内存)
如果希望内存是连续的(比如提升缓存命中率),可以直接分配一维数组,通过索引计算来模拟二维访问:
// 分配连续的int数组,总大小为vertexCount*vertexCount int* fwdistance = malloc(vertexCount * vertexCount * sizeof(int)); int* fwnext = malloc(vertexCount * vertexCount * sizeof(int)); // 初始化时用 i*vertexCount + j 来定位二维数组中的元素 for (int i = 0; i < vertexCount; i++) { for (int j = 0; j < vertexCount; j++) { fwdistance[i * vertexCount + j] = INT_MAX; fwnext[i * vertexCount + j] = -1; } } // 后续访问元素时同样用这个索引公式,比如要取fwdistance[i][j]就写: // fwdistance[i * vertexCount + j]
这种方式的好处是内存连续,释放时只需要调用一次free即可完成内存回收。
内容的提问来源于stack exchange,提问作者Biffins
相关产品推荐
相关产品推荐

