当一个条件不满足,函数要退出时,已经申请的内存没有释放,但是又需要return的情况下,可以使用goto
以下边的函数为例,在判断if(pRet[i] == NULL)
时,如果为空时,如果直接return
的话,那么已经申请内存的pRet
则成了流浪儿,未能完全释放。在这种情况下就可以使用return
语句直接调到程序的末尾去执行释放的操作。
/*
* @fn Merge
* @brief 根据输入的int变量求其对应的hash值
* @param[in] intervals: 需要合并的数组
intervalsSize: 需要合并的数组的大小
intervalsColSize: 需要合并的数组的数量
* @param[out] returnSize: 合并区间后数组的大小
returncolumnSizes: 合并区间后数组的数量
* @return int: 根据哈希生成的key值
*
* @detail
* @date 2021-7-20
*/
int** Merge(_In_ int** intervals, _In_ int intervalsSize, _In_ int* intervalsColSize,
_Out_ int* returnSize, _Out_ int** returnColumnSizes)
{
// 如果只有一个区间,直接返回 TODO:有必要的情况下-》申请内存
if(intervalsSize == 1)
{
return intervals;
}
int nItem = 0;
// 第一个元素从小到大排序;如果第一个元素相等,则根据第二个元素从小到大排序
qsort(intervals, intervalsSize, sizeof(int *), Compare);
int **pRet = (int**)malloc(sizeof(int*)*ARRSIZE_MAX_N);
if(pRet == NULL) {
return NULL;
}
// 定义返回指针
for(int i=0; i<intervalsSize; i++)
{
pRet[i] = (int*)malloc(sizeof(int)*intervalsColSize[0]);
if(pRet[i] == NULL)
{
- return NULL;
+ goto END;
}
memset(pRet[i],0,sizeof(int)*intervalsColSize[0]);
}
// 先将第一个区间存入
pRet[nItem][0] = intervals[0][0];
pRet[nItem][1] = intervals[0][1];
//遍历合并到pRet
for(int i=0; i < intervalsSize; i++)
{
// 当前区间起点小于合并区间终点-》覆盖
if(intervals[i][0] <= pRet[nItem][1] && intervals[i][1] >= pRet[nItem][1])
{
pRet[nItem][1] = intervals[i][1];
}
// 当前区间的起点大于合并区间的终点-》下一节点
else if(intervals[i][0] > pRet[nItem][1])
{
(nItem)++;
pRet[nItem][0] = intervals[i][0];
pRet[nItem][1] = intervals[i][1];
}
}
// 返回结果
*returnSize = nItem + 1;
*returnColumnSizes = intervalsColSize;
return pRet;
// Issue
+END:
+ free(pRet);
+ return NULL;
}