Непонятное поведение memcpy, как перестать перекрывать - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть следующий класс:

BridgingPacketHeader header;
uint32_t ownedByReceiver;
uint32_t nameLength;
uint32_t idLength;
uint32_t uriLength;
char* id;
char* name;
char* uri;

BridgingPacketHeader - это класс из 5 значений uint32_t, поэтому его размер составляет 20 байтов.Я пытаюсь правильно заполнить информацию о длине и скопировать некоторую информацию в id, name и uri, используя memcpy, однако во время отладки поведение странное.Имя и значения URI перекрываются.

Код:

                //SubCcuPacket *subCcuPk = nullptr;
            uint32_t packet_size = (uint32_t) sizeof(SubCcuPacket);
            //Ensuring the total packet size is correct
            uint32_t idLength = (uint32_t)(std::strlen(subCcu1.second.id) + 1);
            packet_size += idLength;
            uint32_t uriLength = (uint32_t)(std::strlen(subCcu1.second.uri) + 1);
            packet_size += uriLength;
            uint32_t nameLength = (uint32_t)(std::strlen(subCcu1.second.name) + 1);
            packet_size += nameLength;

            SubCcuPacket * subCcuPk = (SubCcuPacket*)malloc(packet_size);
            if (sentUri == subCcu1.second.uri) {
                subCcuPk->ownedByReceiver = 1; //if equal uri
            }
            else {
                subCcuPk->ownedByReceiver = 0; //if sub ccu is not same as reciever
            }       

            subCcuPk->idLength = idLength;
            memcpy(&subCcuPk->id, subCcu1.second.id, idLength);

            subCcuPk->nameLength = nameLength;
            memcpy(&subCcuPk->name, subCcu1.second.name, nameLength);

            subCcuPk->uriLength = uriLength;
            memcpy(&subCcuPk->uri, subCcu1.second.uri, uriLength);

            s->send_packet((uint8_t *)subCcuPk, packet_size);

Ниже приведены скриншоты поведения в памяти после каждого memcpy с использованием информации:

subCcu1.second.uri = 10.92.84.162
subCcu1.second.name = bridgex1
subCcu1.second.id = 1

enter image description here enter image description here enter image description here

Как вы можете видеть, в ходе работы программы третий memcpy перекрывал имя в памяти, любоеподсказки относительно того, что может быть причиной этого?Я слышал кое-что о символьных указателях и 4 байтах, что может быть причиной того, что bridgex1 обрезается после 4 байтов, но я не уверен, как решить эту проблему.

1 Ответ

0 голосов
/ 21 февраля 2019

Если у вас есть структура, подобная

struct packet {
    BridgingPacketHeader header;
    uint32_t ownedByReceiver;
    uint32_t nameLength;
    uint32_t idLength;
    uint32_t uriLength;
    char* id;
    char* name;
    char* uri;
};

, id, name и uri являются указателем на память в буфере.Если вы хотите его сериализовать, вам, в основном, придется вручную добавлять их вместе и отслеживать размер фрагментов памяти.

Проще было бы сделать

struct packet {
    BridgingPacketHeader header;
    uint32_t ownedByReceiver;
    uint32_t nameLength;
    uint32_t idLength;
    uint32_t uriLength;
    char id[20];
    char name[20];
    char uri[20];
};

, потому что тогдаsizeof действительно работает, и каждый параметр может содержать до 19 символов (плюс нулевой терминатор).

...