我有一个简单的程序,用于填充2D动态字符数组。分配像往常一样工作。我的问题依赖于释放数组。我在VC ++ 2008上使用纯C。
当我分配和初始化我的数组时,这是一段代码:
char** messsages = (char**)malloc(5*sizeof(char*));
initValorArrayMsgs(messsages, 5);
insertMsgToArray(5, messsages , "Test message.");
void insertMsgToArray(int totalLines, char** msgsArray, const char* msgToInsert)
{
int line = 0;
int size= strlen(msgToInsert);
for(; line < totalLines; line ++)
{
if(strlen(msgsArray[line ]) == 0)
{
msgsArray[line ] = (char*)malloc(sizeof(char) * size);
strcpy(msgsArray[line], msgToInsert);
break;
}
}
}
这是我释放数组的代码
void freeArrayMsgs(char** arry, int lines)
{
int i = 0;
for(; i < lines; i++)
{
if(strlen(arry[i]) == 0){
break;
}
free(arry[i]);
}
free(arry);
}
当程序试图释放第一个数组时,它会引发堆腐败异常。
在SO上阅读一些帖子,我正在解放我的阵列。那么,为什么我会得到肝脏腐败例外?
答案 0 :(得分:3)
一些事情:
malloc(size + 1)
以适应空终结符。sizeof(char)
- sizeof
按char
定义,因此始终为1。malloc
的结果 - 这是不必要的,可能会隐藏问题。msgsArray
未初始化,因此无法保证strlen(msgsArray[line]) == 0
。事实上,它可能不会。如果您希望这样做,请使用calloc
代替malloc
。strncpy
代替strcpy
- 它更安全。strlen
初始化为char*
并检查null
,而不是使用null
。如果第一个msgToInsert
是一个空字符串,但其余的是真正的字符串怎么办?您的代码将退出循环,因为strlen(msgs[0]) == 0
会检查null
而不是修复。答案 1 :(得分:0)
有两件事突然袭来我:
freeArrayMsgs
的内部逻辑似乎是可疑的:在第一个NULL指针上,它会停止循环。
for ( ; i < lines; i++)
{
if (strlen (arry[i]) == 0)
break;
free (arry[i]);
}
也许这没关系,但如果lines
是有史以来使用的最大值,那么将它们全部搞定就很重要了。请注意,释放偶数NULL指针是完全正确的 - 这样做是无操作的。
如果代码重用了指针,那么在free()之后它真的应该将它们清空。如果我看到代码中隐含的相同哲学在整个代码中都存在,那么您可能会重用一个释放的指针,因为存储的指针不是NULL。这很容易解决:
for ( ; i < lines; i++)
{
free (arry[i]);
arry[i] = NULL;
}