std :: copy导致“变量周围的堆栈已损坏”错误

问题描述 投票:0回答:1

我目前正在尝试将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;
}
c++ stl copy
1个回答
1
投票

rxCommandStringLengthint,因此&rxCommandStringLengthint*。为了便于讨论,我们假设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));
© www.soinside.com 2019 - 2024. All rights reserved.