我如何声明一个未知大小的结构
How can I declare a structure of an unknow size?
我有这样的结构:
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类型
如果这是一个C程序,你得到的错误是因为你试图给一个数组赋值,这是不可能的。你只能复制到数组:
memcpy(packet->data, "kappa", 5);
还请注意,如果您希望数据是C字符串,则需要为字符串结束符' '
分配一个额外的字符。然后你可以用strcpy
代替上面的memcpy
。或strncpy
,最多复制特定数量的字符,但随后可能需要手动终止字符串。
但是,这应该在c++中根本不起作用,除非您的编译器将其作为扩展。
不能这样赋值字符串。您需要为字符串分配额外的内存,然后将其复制到数据指针中。
struct A {
size_t datasize;
char data[0]; // flexible member must appear last.
};
A* create_A(const char* str)
{
size_t datasize = strlen(str) + 1; // null terminated (?)
A* p = reinterpret_cast<A*>(new char[sizeof(A) + datasize]);
memcpy(p->data, str, datasize);
p->datasize = datasize;
return p;
}
A* p = create_A("data string");
此方案仅适用于支持零长度或灵活数组的环境。事实上,更好的解决方案可能是用C编写套接字代码,并导出该接口以便在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 ");
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 ");
// 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
。然后可以自动检索dataLength
作为向量的大小,并且始终可以防止溢出。
相关文章:
- 如何循环打印顶点结构
- 重载运算符>>() 表示未知的输入长度/结构
- 具有未知结构作为成员的类
- 将未知结构(在运行时)作为模板参数传递
- MessagePack C++-如何遍历未知的数据结构
- 当通过结构中的指针引用COM_PTR的向量时,向量大小未知时崩溃
- 在编译时初始化一个C++结构,就像一个未知绑定的数组
- 如何保存未知大小的结构(供以后检索)
- c++正在将未知结构转换为字符串
- 在C++结构中处理未知类型的最佳方法是什么?
- C++ 在.h文件中使用带有结构的模板,得到未知错误
- 如何创建和使用指向类中未知数量结构的数组的指针
- 返回结构中从c到Swift的未知长度数组
- 对从c#传递的未知c结构进行迭代
- 从未知结构C++构造一个树(非二进制)结构
- 错误c2036:结构的大小未知
- 具有未知数据类型的c++结构
- 我如何声明一个未知大小的结构
- 在结构中创建未知数据类型数组
- 在c/c++中实现未知表模式的数据结构