我尝试制作char
的动态2D数组,如下所示:
char** ppMapData = (char**)malloc(sizeof(char*)*iMapHeight);
for (int i=0; i< iMapHeight; i++)
{
ppMapData[i] = (char*)malloc(sizeof(char)*iMapWidth);
//do something
}
// do something
for (int i=0; i<iMapHeight; i++)
free(ppMapData[i]);
free(ppMapData);
对我来说很好看;但是,当涉及到运行时,我的程序在调用free(ppMapData[i])
的行崩溃。任何想法在这里有什么问题。
非常感谢你。
答案 0 :(得分:8)
快速浏览一下,自由看起来很好。您应该测试的下一件事是确保您不会在结束时超出任何这些数组。这可能会导致内存分配系统出现问题。
如果您使用的是visual studio,则可以调用_CrtCheckMemory来帮助验证您是不是在捣乱。该调用仅适用于DEBUG构建。
答案 1 :(得分:4)
你在malloc之后检查了NULL值吗?
答案 2 :(得分:2)
您已将自己的问题标记为“C ++”。为什么不使用适当的C ++构造呢?例如。一个vector<vector<char> >
或者甚至(可能我建议)vector<string>
?
编辑哦,vector<string>
可能不是你想要的。不过,我强烈建议使用C ++解决方案。
答案 3 :(得分:2)
乍一看我没有看到问题,但这并不意味着它不存在。请确保你没有通过释放“做某事”部分中的某个内存来实现双重免费。
答案 4 :(得分:2)
如果它是两个维度都有固定大小的二维数组,我总是更喜欢:
char* array = (char*)malloc(iMapHeight*iMapWidth);
使用以下方式访问它:
char val = array[height*iMapWidth + width];
如果您愿意,请在宏中包装:
#define GET_VAL(h, w) array[h*iMapWidth + w]
乘法将比取消引用两个指针以找到值更快。
答案 5 :(得分:2)
一些可能的答案:
您确定不会超出已分配数组的末尾吗? malloc将在您分配的内存后立即存储重要信息,如果您覆盖它,将会发生不好的事情。
您确定要修改ppMapData中的值吗?试图释放从未分配的指针通常也是一件坏事。
程序崩溃时i的价值是多少?它一致吗?知道这会有所帮助,也可能具有指导意义
一些风格评论:
检查malloc的返回值(如果失败则为NULL)。
不要强制转换malloc的返回值(如果你确实在编写C而不是C ++)。
答案 6 :(得分:0)
假设//做某事不仅仅是评论,请取出
//做点什么
代码并查看它是否仍然崩溃。一次添加一个东西,直到它再次崩溃
答案 7 :(得分:0)
从问题中的代码来看,似乎你没有检查malloc是否成功。检查malloc没有返回NULL作为第一步,它可能不是你的问题
//do something
可能使用新分配的内存,但如果不是这样,malloc可能会失败,你知道直到它被免费取消。 (我知道malloc不太可能失败,除非你正在开发低内存环境,但它仍然值得检查)
其次崩溃时i
值是什么,它几乎相同?
最后,您能否为我们提供核心转储,问题更易于识别:)
答案 8 :(得分:0)
如果删除“执行某些操作”代码,它是否仍会崩溃?如果没有,这可能意味着你在“做某事”代码中打破内存,这就是你的错误所在,而不是上面的代码。
如果你在一个支持它的平台上,通过Valgrind运行它,找到微妙的错误是无价的。
答案 9 :(得分:0)
作为joemucchiello的替代品,
char **ppMapData = malloc(iMapHeight * sizeof(char*) +
iMapHeight * iMapWidth * sizeof(char)));
for (int i = 0; i < iMapHeight; i++) {
ppMapData[i] = (char *)(ppMapData + iMapHeight) + i * iMapWidth;
/* do something */
}
/* do something */
free(ppMapData);
这会产生一个大的分配,包含指针数组和字符数组数组。
然而,正如许多其他人所说,您发布的代码运行良好。 “// do something
”段中必须存在未发布的导致此错误的内容。
例如,如果您已经释放ppMapData[i]
,则无法再次释放它。有些人会通过在ppMapData[i] = NULL
之后立即设置free(ppMapData[i])
来避免这种情况:这是有效的,因为free(NULL)
是合法的,什么都不做。我的偏好是不来执行此操作,以及修复任何可以导致双重免费情况的设计。
答案 10 :(得分:-1)
iMapHeight / iMapWidth是否常量?如果没有,它们之间可能会发生变化,从而导致问题。 另外,正如其他人所建议的那样,检查malloc是否返回null。