简体   繁体   中英

Converting byte* to std::string with 8 or less bytes causes a crash

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 

Live demo


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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM