在一些函数中,我需要用malloc()分配内存,并有几个if.else语句,如伪代码所示:
allocate memory
if condition_1
do_stuff
if condition_2
do_more_stuff
else
error
else
error
free allocated memory
return
所以我在一开始就分配内存,如果一切正常,它就会被释放。但目前,错误功能只打印一条错误消息并退出该程序。但正如我经常读到的那样,不释放内存——尽管当程序退出并且操作系统正常处理之后的释放时,这不是一种好的风格。我怎么能懒洋洋地把钱放出来?我是否必须编写一个错误函数,将指向我分配的内存的每个指针都释放,指针可能是不同的数据类型?或者我应该在调用错误函数之前放free(ptr)吗?一个错误函数采用一个数据类型为void和freedom的指针数组,这样做会奏效吗?
我有两个解决方案。
您可以在呼叫free
和error
:的位置贴上标签
void function(void)
{
Memory *p = malloc(sizeof(*p));
if (condition_1) {
do_stuff();
if (condition_2) {
do_more_stuff();
} else {
goto err;
}
} else {
goto err;
}
free(p);
return;
err:
free(p);
error();
}
您也可以使用标志来标记错误:
void function(void)
{
Memory *p = malloc(sizeof(*p));
bool err = false;
if (condition_1) {
do_stuff();
if (condition_2) {
do_more_stuff();
} else {
err = true;
}
} else {
err = true;
}
free(p);
if (err)
error();
}
我认为第二种解决方案在这种情况下看起来最好,但它们都同样有效。
不要使用goto。使用一次性while。此外,如果您需要一个错误标志,请将其默认为true而不是false以保存代码:
...malloc...
err = 1;
do {
...
if <condition> break;
...
if <condition> break;
...
if <condition> break;
...
err = 0;
} while (0);
...free...
if (err) ...
据我所知,当您因错误退出程序时,您关心释放所有内存,但不想手动处理所有指针。
这里有一个有趣的想法,写一个函数allocMemory,它返回malloc的结果,但也将指针放入链表中,然后freeMemory将其从列表中删除,最后释放所有在列表上迭代并释放所有指针的函数。使用allocMemory和freeMomory函数,而不是malloc和free,并在出现错误时调用freeMemory函数。