我有这个结构:
struct __attribute__((packed)) BabelPacket
{
unsigned senderId;
unsigned dataLength;
unsigned char data[0];
};
并声明我这样做:
BabelPacket *packet = reinterpret_cast<BabelPacket *>(new char[sizeof(BabelPacket) + 5]);
packet->senderId = 1;
packet->data = "kappa";
packet->dataLength = 5;
但是当我编译的时候我有这个错误:
error: incompatible types in assignment of ‘const char [6]’ to ‘unsigned char [0]’
packet->data = "kappa";
^
你知道我该怎么做吗?
而且我需要通过套接字发送此结构,以将对象恢复到服务器中,因此我只能使用C类型。
最佳答案
如果您愿意/允许将unsigned char
更改为常规char
,则可以使用strcpy
:
#include <iostream>
#include <stdio.h>
#include <string.h>
struct __attribute__((packed)) BabelPacket
{
unsigned senderId;
unsigned dataLength;
char data[0]; // I changed this to char in order to use strcpy
};
int main(){
BabelPacket *packet = reinterpret_cast<BabelPacket *>(new char[sizeof(BabelPacket) + 5]);
packet->senderId = 1;
// Copy the string. Add NULL character at the end of
// the string to indicate its end
strcpy(packet->data, "kappa\0");
packet->dataLength = 5;
// Verify that the string is copied properly
for (int i=0;i<packet->dataLength;++i){
std::cout<<packet->data[i];
}
std::cout<<std::endl;
return 0;
}
请注意,这仅在
data
位于struct
的末尾时才起作用,否则,就没有连续的内存来分配data
。如果我将元素的顺序交换为:struct __attribute__((packed)) BabelPacket
{
unsigned senderId;
char data[0]; // I changed this to char in order to use strcpy
unsigned dataLength;
};
上面代码的输出(而不是“kappa”)将是“a”。
如果确定要使用C数组,一种更可靠的方法是假设最大数量的元素并预分配数组,即:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_NUMBER_OF_CHARACTERS 5 // Many ways to do this, I defined the macro for the purposes of this example
struct __attribute__((packed)) BabelPacket
{
unsigned senderId;
// I changed this to char in order to use strcpy. Allocate the
// max number + 1 element for the termination string
char data[MAX_NUMBER_OF_CHARACTERS+1];
unsigned dataLength;
};
int main(){
BabelPacket *packet = reinterpret_cast<BabelPacket *>(new char[sizeof(BabelPacket) + 5]);
packet->senderId = 1;
packet->dataLength = 5;
if (dataLength>MAX_NUMBER_OF_CHARACTERS){
std::cout<<"String greater than the maximum number of characters"<<std::endl;
}
// Copy the string. Add NULL character at the end of
// the string to indicate its end
strcpy(packet->data, "kappa\0");
// Verify that the string is copied properly
for (int i=0;i<packet->dataLength;++i){
std::cout<<packet->data[i];
}
std::cout<<std::endl;
return 0;
}
此代码产生正确的输出,并保护您免受违规。如您所见,它很快就会变得困惑,这就是为什么我建议为此使用
std::vector
的原因。然后可以按照 vector 的大小自动检索dataLength
,并且始终可以防止溢出。关于c++ - 如何声明未知大小的结构?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40083374/