可变大小的结构C ++ [英] Variable Sized Struct C++
问题描述
这是在C ++中使用可变大小的结构体的最好方法吗?我不想使用向量,因为长度在初始化后不会改变。
struct Packet
{
unsigned int bytelength;
unsigned int data [];
};
包* CreatePacket(unsigned int length)
{
Packet * output =(Packet *)malloc((length + 1)* sizeof(unsigned int)
output-> bytelength = length;
return output;
}
编辑:重命名变量名称和更改的代码更正确。 >
关于您正在做什么的一些想法:
-
使用C风格的可变长度struct idiom,您可以为每个包执行一个空闲存储分配,这是
struct Packet
包含std :: vector
。如果您正在分配大量的数据包,那么执行一半的空闲存储分配/释放可能非常重要。如果您也在进行网络访问,则等待网络的时间可能会更大。 -
此结构表示一个数据包。你计划从套接字直接读/写到
struct Packet
?如果是这样,你可能需要考虑字节顺序。在发送数据包时,您是否要从主机转换为网络字节顺序,反之亦然?如果是这样,那么可以在可变长度结构中将数据字节交换到位。如果将它转换为使用向量,编写用于序列化/反序列化包的方法将是有意义的。 -
同样,您可能需要考虑对齐和打包。 / p>
-
您不能将
包
-
而不是
malloc
free
,您可以使用Packet * p = :: operator new(size)
和: :operator delete(p)
,因为struct Packet
是POD类型,目前不受益于其默认构造函数及其析构函数。这样做的(潜在的)好处是,全局运算符新
使用全局新处理程序和/或异常处理错误,如果这对你很重要。 -
可以使变长度struct idiom使用new和delete操作符,但不是很好。你可以通过实现
static void * operator new(size_t size,unsigned int bitlength)创建一个自定义
运算符new
$ c>,但你仍然必须设置bitlength成员变量。如果你用一个构造函数做到这一点,你可以使用稍微冗余的表达式Packet * p = new(len)Packet(len)
来分配一个包。与使用全局运算符新
和运算符delete
相比,我看到的唯一好处是,您的代码的客户端可以调用delete p
而不是:: operator delete(p)
。在单独的函数中包装分配/释放(而不是直接调用delete p
)就可以了。
Is this the best way to make a variable sized struct in C++? I don't want to use vector because the length doesn't change after initialization.
struct Packet
{
unsigned int bytelength;
unsigned int data[];
};
Packet* CreatePacket(unsigned int length)
{
Packet *output = (Packet*) malloc((length+1)*sizeof(unsigned int));
output->bytelength = length;
return output;
}
Edit: renamed variable names and changed code to be more correct.
Some thoughts on what you're doing:
Using the C-style variable length struct idiom allows you to perform one free store allocation per packet, which is half as many as would be required if
struct Packet
contained astd::vector
. If you are allocating a very large number of packets, then performing half as many free store allocations/deallocations may very well be significant. If you are also doing network accesses, then the time spent waiting for the network will probably be more significant.This structure represents a packet. Are you planning to read/write from a socket directly into a
struct Packet
? If so, you probably need to consider byte order. Are you going to have to convert from host to network byte order when sending packets, and vice versa when receiving packets? If so, then you could byte-swap the data in place in your variable length struct. If you converted this to use a vector, it would make sense to write methods for serializing / deserializing the packet. These methods would transfer it to/from a contiguous buffer, taking byte order into account.Likewise, you may need to take alignment and packing into account.
You can never subclass
Packet
. If you did, then the subclass's member variables would overlap with the array.Instead of
malloc
andfree
, you could usePacket* p = ::operator new(size)
and::operator delete(p)
, sincestruct Packet
is a POD type and does not currently benefit from having its default constructor and its destructor called. The (potential) benefit of doing so is that the globaloperator new
handles errors using the global new-handler and/or exceptions, if that matters to you.It is possible to make the variable length struct idiom work with the new and delete operators, but not well. You could create a custom
operator new
that takes an array length by implementingstatic void* operator new(size_t size, unsigned int bitlength)
, but you would still have to set the bitlength member variable. If you did this with a constructor, you could use the slightly redundant expressionPacket* p = new(len) Packet(len)
to allocate a packet. The only benefit I see compared to using globaloperator new
andoperator delete
would be that clients of your code could just calldelete p
instead of::operator delete(p)
. Wrapping the allocation/deallocation in separate functions (instead of callingdelete p
directly) is fine as long as they get called correctly.
这篇关于可变大小的结构C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!