Преобразовать строку в символ без знака и [] - PullRequest
0 голосов
/ 27 апреля 2011

У меня в настоящее время есть пакет, настроенный следующим образом:

struct Packet {
    unsigned short sequenceNumber;
    unsigned short length;
    unsigned char control;
    unsigned char ack;
    unsigned short crc;
    unsigned char data[];
    Packet copy(const Packet& aPacket) {
        sequenceNumber = aPacket.sequenceNumber;
        length = aPacket.length;
        control= aPacket.control;
        ack = aPacket.ack;
        crc = aPacket.crc;
        memcpy (data, aPacket.data, aPacket.length);
    }
};

Этот пакет преобразуется в строку для шифрования и затем должен быть взят из его расшифрованной строковой формы обратно в пакет.Я могу сделать это нормально для всех переменных, за исключением unsigned char data[].Я пробовал следующее безуспешно:

string data = thePack.substr(pos, thePack.length()-pos);
    unsigned char * cData = new unsigned char[data.length()];
    strcpy((char *)cData, data.c_str());
    memcpy(p.data, cData, data.length());

, где data - строковое представление данных, которые должны быть скопированы в unsigned char [], а p - пакет.

Это даетследующее из valgrind:

==16851== Invalid write of size 1

==16851==    at 0x4A082E7: strcpy (mc_replace_strmem.c:303)

Несмотря на то, что он ссылается на strcpy в качестве источника, он компилируется и работает нормально только с закомментированной строкой memcpy.

Я также попытался заменитьmemcpy с strcpy с тем же результатом.Есть идеи?Я чувствую, что это может быть связано с тем фактом, что данные, возможно, не были инициализированы и для них не было выделено никакой памяти, но я думал, что memcpy позаботится об этом.

Ответы [ 2 ]

3 голосов
/ 27 апреля 2011

Вы не указали размер массива data.

unsigned char data[];

Это допустимо, но довольно сложно в использовании.Массив data будет следовать за остальной структурой Packet в памяти, но компилятор не знает, сколько места для него выделено.Таким образом, вы должны выделить дополнительное пространство самостоятельно:

size_t datalen = thePack.length()-pos;
void* pbuffer = malloc( sizeof (Packet) + datalen + 1 );
Packet* p = new (pbuffer) Packet;
memcpy(p.data, &thePack[pos], datalen);
p.data[datelen] = 0;

Что не сработает, так это то, что компилятор сам решит, насколько большим должен быть Packet, используя new Packet или локальную переменную Packet p;,Это закончится без места, зарезервированного для data.И нет, memcpy не выделяет память.

Гораздо более чистым решением было бы использование std::vector для массива данных переменного размера.

1 голос
/ 27 апреля 2011

Вы выделяете char[] на один символ слишком мало - вы должны оставить место для байта NULL в конце:

unsigned char * cData = new unsigned char[data.length() + 1];

Используйте версию strcpy для копирования строки,поэтому байт NULL копируется правильно.Несмотря на то, что он может работать без этого +1, гарантии нет, а иногда может произойти сбой.

...