将字符串转换为 unsigned char[]

发布于 2024-11-03 12:46:23 字数 1256 浏览 0 评论 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 行即可编译并正常运行。

我还尝试用 strcpy 替换 memcpy ,结果相同。有什么想法吗?我觉得这可能是由于数据可能尚未初始化并且没有为其分配任何内存,但我认为 memcpy 会解决这个问题。

I currently have a Packet set up like so:

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);
    }
};

This packet gets converted into a string for encryption and then needs to be taken from its decrypted string form back to a Packet. I am able to do this fine for all of the variables except for the unsigned char data[]. I have tried the following with no success:

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());

where data is the string representation of the data to be copied into the unsigned char [] and p is the Packet.

This gives the following from valgrind:

==16851== Invalid write of size 1

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

Even though it cites strcpy as the source, it compiles and runs fine with just the memcpy line commented out.

I have also tried replacing memcpy with strcpy with the same result. Any ideas? I feel that it might be due to the fact that data may have not been initialized and there for not have any memory allocated to it, but I thought memcpy would take care of this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

枕头说它不想醒 2024-11-10 12:46:23

您尚未指定 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 或局部变量<代码>数据包p;。这最终将导致没有为数据保留空间。不,memcpy 不分配内存。

一个更简洁的解决方案是使用 std::vector 来存储可变大小的数据数组。

You haven't specified the size of the data array.

unsigned char data[];

This is legal, but rather difficult to use. The data array will follow the rest of the Packet structure in memory, but the compiler doesn't know how much space to allocate for it. So you have to allocate the extra space yourself:

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;

What won't work is letting the compiler decide how big a Packet should be, either using new Packet or a local variable Packet p;. That will end up with no space reserved for data. And no, memcpy doesn't allocate memory.

A much cleaner solution would be to use a std::vector for your variable-sized data array.

盛夏已如深秋| 2024-11-10 12:46:23

您分配的 char[] 太小了 - 您必须在末尾为 NULL 字节留出空间:

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

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

The char[] you're allocating is one character too small -- you must leave room for the NULL byte at the end:

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

Use the strcpy version to copy the string, so the NULL byte gets copied correctly. Although it might run OK without that +1, there's no guarantee, and sometimes it might crash.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文