执行“free(ppMapData [i])”时程序崩溃了什么?

时间:2008-12-11 21:51:59

标签: c arrays memory-management

我尝试制作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])的行崩溃。任何想法在这里有什么问题。 非常感谢你。

11 个答案:

答案 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)

一些可能的答案:

  1. 您确定不会超出已分配数组的末尾吗? malloc将在您分配的内存后立即存储重要信息,如果您覆盖它,将会发生不好的事情。

  2. 您确定要修改ppMapData中的值吗?试图释放从未分配的指针通常也是一件坏事。

  3. 程序崩溃时i的价值是多少?它一致吗?知道这会有所帮助,也可能具有指导意义

  4. 一些风格评论:

    • 检查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。