将字符串转换为unsigned char []

时间:2011-04-27 04:02:22

标签: c++ arrays cstring unsigned-char

我目前的数据包设置如下:

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 个答案:

答案 0 :(得分:3)

您尚未指定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 :(得分:1)

你要分配的char[]是一个太小的字符 - 你必须在最后为空字节留出空间:

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

使用strcpy版本复制字符串,以便正确复制NULL字节。虽然没有+1可能会运行正常,但无法保证,有时可能会崩溃。