令人困惑的 memcpy 行为,如何停止重叠
Confusing memcpy behaviour, how to stop overlapping
我有以下 class:
BridgingPacketHeader header;
uint32_t ownedByReceiver;
uint32_t nameLength;
uint32_t idLength;
uint32_t uriLength;
char* id;
char* name;
char* uri;
BridgingPacketHeader 是一个 class 的 5 uint32_t 值,因此它的大小是 20 个字节。
我正在尝试使用 memcpy 正确填写长度信息并将一些信息复制到 id、name 和 uri 中,但是在调试时,行为很奇怪。名称和 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
如您所见,随着程序的运行,第三个 memcpy 与内存中的名称重叠,是否有关于可能导致此问题的线索?我听说过一些关于字符指针和 4 个字节的事情,这可能就是为什么 bridgex1 在 4 个字节后被切断的原因,但我不确定如何解决这个问题。
如果你有一个像
这样的结构
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 个字符(加上空终止符)。
我有以下 class:
BridgingPacketHeader header;
uint32_t ownedByReceiver;
uint32_t nameLength;
uint32_t idLength;
uint32_t uriLength;
char* id;
char* name;
char* uri;
BridgingPacketHeader 是一个 class 的 5 uint32_t 值,因此它的大小是 20 个字节。 我正在尝试使用 memcpy 正确填写长度信息并将一些信息复制到 id、name 和 uri 中,但是在调试时,行为很奇怪。名称和 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
如您所见,随着程序的运行,第三个 memcpy 与内存中的名称重叠,是否有关于可能导致此问题的线索?我听说过一些关于字符指针和 4 个字节的事情,这可能就是为什么 bridgex1 在 4 个字节后被切断的原因,但我不确定如何解决这个问题。
如果你有一个像
这样的结构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 个字符(加上空终止符)。