看下面这段代码:
void ABCD::CopyData(int nMsgCode, int** ppParam, int nLen) {
VisionBingoMessage* psBingoData = NULL;
ASSERT(sizeof(VisionBingoMessage) == nLen);
psBingoData = new VisionBingoMessage;
memcpy(psBingoData, *ppParam, nLen);
psBingoData->nLength = ((VisionBingoMessage*)(*ppParam))->nLength;
psBingoData->pnBoardStatus = (eint32*)malloc(sizeof(int32) * (psBingoData->nLength));
memcpy(psBingoData->pnBoardStatus, ((VisionBingoMessage*)(*ppParam))->pnBoardStatus,
sizeof(eint32) * (psBingoData->nLength));
psBingoData->pvCornorPointsLists = new vector<VisionMarker>;
*psBingoData->pvCornorPointsLists = *(((VisionBingoMessage*)(*ppParam))->pvCornorPointsLists);
return;
(这段代码已经被改过, 是没有问题的 !)
}
函数功能解释,将传进来的数据拷贝一份;
其中 memcpy(psBingoData,*ppParam,nLen)中nlen必须是VisionBingoMessage结构体的长度(即sizeof(VisionBingoMessage)), 而不是数据包的长度(因为结构体里有指向数组和vector的指针,所以数据包的长度肯定比结构体的长度要大);
至于原因,是这样的,
psBingoData = new VisionBingoMessage;
memcpy(psBingoData,*ppParam,nLen);
用new分配内存的时候,编译器会告诉操作系统分配一个跟psBingoData所对应类型一样长度的内存,即sizeof(VisionBingoMessage).
而下面memcpy时, 如果nlen>sizeof(VisionBingoMessage).就会写超.
写超之后,当再分配内存时,操作系统会从VisionBingoMessage长度之后紧接着的一块内存开始分配,而这时操作系统发现这块内存已经被写过了,程序就会崩!