strncpy踩过的坑

一、表象

下面这段代码的for循环,不进入循环,断点检查list里边是有元素的

    FOR_EACHDATA_INLIST(&Cfg_GetPtzMng()->stPresetList, pstPresetNode, stIterator)
    {
        if(pstPresetNode->ucUseFlag == 0)
        {
            continue;
        }
        hArryObject = iTrd_Json_CreateObject();
        iTrd_Json_AddItemToArray(hArry,hArryObject); 
        
        iTrd_Json_AddItemToObject(hArryObject,(_UC*)"PresetId",iTrd_Json_CreateStrWithNum(pstPresetNode->uiPresetId));
        iTrd_Json_AddItemToObject(hArryObject,(_UC*)"Name",iTrd_Json_CreateString(pstPresetNode->aucName));
        iTrd_Json_AddItemToObject(hArryObject,(_UC*)"PicID",iTrd_Json_CreateString(pstPresetNode->aucPicID));
        hObject = iTrd_Json_CreateObject();
        iTrd_Json_AddItemToObject(hArryObject,(_UC*)"Point",hObject);
        iTrd_Json_AddItemToObject(hObject,(_UC*)"X",iTrd_Json_CreateStrWithNum(pstPresetNode->stPtzPreset.iX));
        iTrd_Json_AddItemToObject(hObject,(_UC*)"Y",iTrd_Json_CreateStrWithNum(pstPresetNode->stPtzPreset.iY));  
    }

二、表因

stPresetList 和 pstPresetNode 无法匹配

三、排查

1、检查pstPresetNode和List的类型是否匹配?

经过检查ok

2、检查pstPresetNode和stPresetList 中Node所占内存是否一致

发现问题:

_INT Cfg_AddPresetPoint(_INT iCamId, _UI uiPresetId,_UC *pucName, ST_ZJ_PRESET_POINT *pstPoint)
{
    ST_COS_LIST_ITERATOR stIterator;
    ST_CFG_PRESET_NODE  *pstPresetNode = COS_NULL;
    ST_CFG_PRESET_NODE  *pstFreeNode   = COS_NULL;

    FOR_EACHDATA_INLIST(&Cfg_GetPtzMng()->stPresetList, pstPresetNode, stIterator)
    {
        if(pstPresetNode->uiPresetId == uiPresetId)
        {
            break;
        }
        else if(pstPresetNode->ucUseFlag == 0)
        {
            pstFreeNode = pstPresetNode;
        }
    }
    
    if(pstPresetNode == COS_NULL)
    {
        if(pstFreeNode == COS_NULL)
        {
            pstPresetNode = (ST_CFG_PRESET_NODE*)COS_MALLOCCLR(sizeof(ST_CFG_PRESET_NODE));
            COS_LIST_ADDTAIL(&Cfg_GetPtzMng()->stPresetList, pstPresetNode);
        }
        else
        {
            pstPresetNode = pstFreeNode;
        }
        pstPresetNode->uiPresetId = uiPresetId;
    }
    COS_MEMCPY(&pstPresetNode->stPtzPreset, pstPoint, sizeof(ST_ZJ_PRESET_POINT));
    COS_STRNCPY(pstPresetNode->aucName, pucName,128);
    pstPresetNode->ucUseFlag = 1;
    Cfg_GetItemSign()->ucSavePtz = 1;
    return COS_OK;;
}

添加到list中的Node节点在初始化的时候发生越界。

倒数第四行COS_STRNCPY(pstPresetNode->aucName, pucName,128)

Node结构体声明中变量aucName是32字节,此处发生越界,有的编译器会直接crash。但是我的编译器就没有,干!

四、最终原因

strncpy的越界行为使得当时添加到stPresetList中的Node越界了4个字节,所以和正常声明的pstPresetNode匹配失败。

 

五、参考

函数原型:char *strncpy(char *restrict s1, const char *restrict s2, size_t n);

man解释:If the array pointed to by s2 is a string that is shorter than n bytes, null bytes shall be appended to the copy in the array pointed to by s1, until n bytes in all are written.

事实上s2往往不如n那么长,于是s1剩余部分会全填0。今天碰到的问题就是,s1的长度不如n,但是dest指向的n的长度全部被改写,于是内存被越界写了0,程序挂掉了

https://blog.csdn.net/mosakashaka/article/details/7456910

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值