我目前正在尝试将vector<BYTE>
中的4个字节复制到一个整数值中。当函数返回时,我不断收到错误消息,表明我的堆栈已损坏(变量“ rxPacket”周围的堆栈已损坏)。我在调试模式下运行并调试DLL。我将函数简化为如下所示的非常基本的内容,但仍然收到结果错误。我确实找到了this issue,并且想知道我是否遇到类似的情况。但是,我想检查一下是否有明显的失踪之处。
AtpSocket::RxPacket AtpSocket::sendAndWait(AtpSocket::Command cmd,const void* data,size_t dataLen,int timeout) {
AtpSocket::TxPacket txPacket;
AtpSocket::RxPacket rxPacket;
int rxCommandStringLength = 0;
std::vector<BYTE> readBuffer(20, 55);
std::reverse_copy(readBuffer.begin(), readBuffer.begin() + sizeof rxCommandStringLength, &rxCommandStringLength);
return rxPacket;
}
rxCommandStringLength
是int
,因此&rxCommandStringLength
是int*
。为了便于讨论,我们假设sizeof(int)
是4个字节1。
1:要真正确保要精确复制4个字节,应该使用int32_t
而不是int
,因为在所有平台上都不能保证int
是4个字节。
迭代器(包括原始指针)根据整个元素而不是字节进行递增/递减。元素类型是取消引用迭代器时返回的任何类型。
由于您的输出迭代器是int*
指针,因此reverse_copy()
将以4字节的跳转而不是您期望的1字节的跳转遍历目标内存。换句话说,当reverse_copy()
增加输入迭代器时,它将向前跳转1个字节,但是当它增加目标迭代器时,它将向前跳转4个字节。
因为您正在遍历4个输入元素,所以目标指针将总共增加16个字节,这超出了实际rxCommandStringLength
变量的范围,因此将导致reverse_copy()
写入周围的内存,从而破坏堆栈(如果不只是崩溃而已)。从vector
中只能读取4个字节,但是将[16]中的16个字节写入到rxCommandStringLength
中,实际上只有前4个字节会实际占用rxCommandStringLength
。
由于要让reverse_copy
以1字节为增量对输入和输出进行迭代,因此需要对int*
指针进行类型转换以匹配输入迭代器使用的数据类型,例如:
std::reverse_copy(readBuffer.begin(), readBuffer.begin() + sizeof rxCommandStringLength, reinterpret_cast<BYTE*>(&rxCommandStringLength));