As the title says, my program is not outputting correctly after converting a byte array that has 8 or less bytes in it and removing the first 4 bytes from the vector, then converting it to a string. Works fine with anything else. I am holding each byte inside of a vector, and I know C++ does not like raw pointers, but it was the easiest solution to work with.
To be specific, the std::string tostring() function is the issue.
Here is my the class I am using:
Edit: Updated with minimal reproducable example. For some reason it won't work at all when I use remove in this example. It works fine in my code unless its less than 8 bytes.
#include <Windows.h>
#include <vector>
#include <sstream>
#include <iomanip>
#include <iostream>
class Packet {
typedef std::vector<byte>::iterator iterator; // for iteration and manipulation of the raw data
typedef std::vector<byte>::const_iterator const_iterator; // for iteration of the const raw data
public:
std::vector<byte> data;
Packet();
Packet(const byte* pdata, size_t cb) { // initializes the packet with a copy of the given data
data.resize(cb);
std::copy(pdata, pdata + cb, data.begin());
}
size_t size() const { // retuns the size in bytes of the packet
return data.size();
}
void clear() {
data.clear();
}
void removeAt(int i) {
delete &(data.begin() + i);
data.erase(data.begin() + i);
}
std::string tostring() const { // formats the packet raw data into a string
std::stringstream ss;
// stringstream flags for formatting
// std::hex = hex number output
// std::setfill('0') = zero fill number formatting
// std::uppercase = uppercase hex letters
ss << std::hex << std::setfill('0') << std::uppercase;
for (auto& b : data) {
ss << std::setw(2) << static_cast<WORD>(b) << " ";
// I have no idea why but the only way to make it
// format it properly is casting it to a 4-byte int
// setw(2) truncates it back to a 2-digit hex number
// setw is not "sticky" so it must be set each time
}
return ss.str();
}
};
int main()
{
/*unsigned char* test = new unsigned char[7];
test[0] = 0x01;
test[1] = 0x02;
test[2] = 0x03;
test[3] = 0x04;
test[4] = 0x05;
test[5] = 0x06;
test[6] = 0x07;
Packet* pPacket = new Packet(test, 7);
pPacket->removeAt(0);
pPacket->removeAt(0);
pPacket->removeAt(0);
pPacket->removeAt(0);*/
byte* test2 = new byte[12];
test2[0] = 0x01;
test2[1] = 0x02;
test2[2] = 0x03;
test2[3] = 0x04;
test2[4] = 0x05;
test2[5] = 0x06;
test2[6] = 0x07;
test2[7] = 0x08;
test2[8] = 0x09;
test2[9] = 0x10;
test2[10] = 0x11;
test2[11] = 0x12;
Packet* pPacket2 = new Packet(test2, 12);
pPacket2->removeAt(0);
pPacket2->removeAt(0);
pPacket2->removeAt(0);
pPacket2->removeAt(0);
std::cout << pPacket2->tostring() << std::endl;
system("pause");
}
I'm assuming that byte
is an alias for unsigned char
and that WORD
is an alias for int
, though this could be wrong.
The line
delete &(data.begin() + i);
makes no sense at all, and removing it fixes the code. GCC gives a clear error about this . I recommend cranking up your compiler warnings and reading them carefully.
main.cpp: In member function ‘void Packet::removeAt(int)’:
main.cpp:28:31: error: taking address of rvalue [-fpermissive]
28 | delete &(data.begin() + i);
| ~~~~~~~~~~~~~~^~~~
Removing this line entirely causes the code to run producing what I think is your expected output:
05 06 07 08 09 10 11 12
Note that your constructor could be using a member initializer list to more efficiently initialize your data
member:
Packet(const byte* pdata, size_t cb)
: data(pdata, pdata + cb) {
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.