0

我目前有一个这样的数据包设置:

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会解决这个问题。

4

2 回答 2

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不起作用的是让编译器决定 a应该有多大,无论是使用new Packet还是局部变量Packet p;。这将最终没有为data. 不,memcpy不分配内存。

一个更清洁的解决方案是将 astd::vector用于可变大小的数据数组。

于 2011-04-27T04:23:36.460 回答
1

你分配的char[]字符太小了——你必须在最后为 NULL 字节留出空间:

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

使用strcpy版本复制字符串,因此 NULL 字节被正确复制。尽管没有 +1 它可能运行良好,但不能保证,有时它可能会崩溃。

于 2011-04-27T04:07:48.907 回答