我正在开发ANSI C中的一个小程序,它生成一个带动态数组的图形。 当我在Visual Studio中运行时,我收到此错误:“程序[X]已触发断点,并在控制台中打印:”释放后,在[B]处修改的自由堆块[A]“。 程序在memalloc指令上停止。 我看到当内存被不正确地释放时会发生这个错误,但在我的情况下,在我调用指令之前发生,我想问题可能是错误的内存重新分配。
代码:
#include "stdafx.h"
#include <stdlib.h>
typedef struct TNode TNode;
struct TNode
{
TNode** nodes;
int nodeCount;
int index;
};
void initialization(int N, TNode * nodes)
{
int n = N;
for (n; n >= 0; --n)
{
nodes[n].nodeCount = 0;
nodes[n].index = n;
}
}
void createGraph(int lastPath, int * J, int * K, TNode * nodes)
{
int i = lastPath;
for (i; i >= 0; --i)
{
int nodeJ = J[i];
int nodeK = K[i];
//nodeJ
int lastNode = nodes[nodeJ].nodeCount;
nodes[nodeJ].nodeCount++;
if (lastNode == 0)
{
nodes[nodeJ].nodes = malloc(sizeof(TNode*) * nodes[nodeJ].nodeCount); //ERROR !!!!
}
else
{
realloc(nodes[nodeJ].nodes, sizeof(TNode*) * nodes[nodeJ].nodeCount);
}
nodes[nodeJ].nodes[lastNode] = &nodes[nodeK];
//nodeK
lastNode = nodes[nodeK].nodeCount;
nodes[nodeK].nodeCount++;
if (lastNode == 0)
{
nodes[nodeK].nodes = malloc(sizeof(TNode*) * nodes[nodeK].nodeCount);
}
else
{
realloc(nodes[nodeK].nodes, sizeof(TNode*) * nodes[nodeK].nodeCount);
}
nodes[nodeK].nodes[lastNode] = &nodes[nodeJ];
}
}
int generate(int J [], int K [], int N){
int intersections = N + 1;
TNode *nodes = malloc((intersections) * sizeof(TNode));
int lastPath = N - 1;
initialization(N, nodes);
createGraph(lastPath, J, K, nodes);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
int J[8] = { 0, 1, 2, 3, 3, 2, 6, 6 };
int K[8] = { 1, 2, 3, 4, 5, 6, 8, 7 };
generate(J, K, 8);
return 0;
}
此外,我尝试在IdeOne上运行程序:https://ideone.com/fBGEuT并且它运行没有问题。 这让我怀疑编译器中可能存在配置问题。
你认为错在哪里?
答案 0 :(得分:1)
这一行(以及另一个realloc
- 调用)是问题所在:
realloc(nodes[nodeJ].nodes, sizeof(TNode*) * nodes[nodeJ].nodeCount);
realloc
返回指向放大的内存区域的指针。此内存区域可能与旧内存区域不同。如果没有空间来扩大旧的存储区域,就会发生这种情况,因为另一个对象就在它后面。请改用这样的东西:
nodes[nodeJ].nodes = realloc(nodes[nodeJ].nodes, sizeof(TNode*) * nodes[nodeJ].nodeCount);
您可能还想检查错误,因为malloc
和realloc
都可能失败。
您的编译器应该发出警告,忽略free
的结果。请不要忽略编译器警告。