goto妙用

当一个条件不满足,函数要退出时,已经申请的内存没有释放,但是又需要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;
}

goto妙用

上一篇:BurpSuitePro激活


下一篇:Hall 定理