Reputation: 507
I am currently trying to copy 4 bytes out of a vector<BYTE>
into an integer value. When my function returns, I continually get an error that my stack is corrupted (Stack around the variable 'rxPacket' was corrupted). I am running in debug mode and debugging my DLL. I stripped the function down to something very basic shown below, but I still get the resulting error. I did find this issue and I'm wondering if I am experiencing something similar. But, I wanted to check to see if there was something obvious I am missing.
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;
}
Upvotes: 0
Views: 105
Reputation: 597166
rxCommandStringLength
is an int
, so &rxCommandStringLength
is an int*
. Let's just assume for the sake of argument that sizeof(int)
is 4 bytes 1.
1: to really ensure that exactly 4 bytes are being copied, you should be using int32_t
instead of int
, since int
is not guaranteed to be 4 bytes on all platforms.
Iterators (which includes raw pointers) are incremented/decremented in terms of whole elements, not bytes. The element type is whatever type is returned when the iterator is dereferenced.
Since your input iterator is a vector::iterator
to a BYTE
array, and your output iterator is an int*
pointer, reverse_copy()
will iterate through the source array in whole BYTE
s and through the destination memory in whole int
s, not in single bytes like you are expecting. In other words, when reverse_copy()
increments the input iterator it will jump forward by 1 byte, but when it increments the destination iterator it will jump forward in memory by 4 bytes.
In this example, reverse_copy()
will read the 1st input BYTE
and write the value to the 1st output int
, then read the 2nd input BYTE
and write the value to the 2nd output int
, and so on, and so on. By the end, the input iterator will have advanced by 4 BYTE
s, and the destination pointer will have advanced by 4 int
s - 16 bytes total, which goes WAY beyond the bounds of the actual rxCommandStringLength
variable, and thus reverse_copy()
will have written into surrounding memory, corrupting the stack (if it doesn't just crash instead).
Since you want reverse_copy()
to iterate in 1-byte increments for BOTH input AND output, you need to type-cast the int*
pointer to match the data type used by the input iterators, eg:
std::reverse_copy(readBuffer.begin(), readBuffer.begin() + sizeof rxCommandStringLength, reinterpret_cast<BYTE*>(&rxCommandStringLength));
Upvotes: 3