可变大小的结构C ++ [英] Variable Sized Struct C++

查看:171
本文介绍了可变大小的结构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 a std::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 and free, you could use Packet* p = ::operator new(size) and ::operator delete(p), since struct 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 global operator 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 implementing static 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 expression Packet* p = new(len) Packet(len) to allocate a packet. The only benefit I see compared to using global operator new and operator delete would be that clients of your code could just call delete p instead of ::operator delete(p). Wrapping the allocation/deallocation in separate functions (instead of calling delete p directly) is fine as long as they get called correctly.

这篇关于可变大小的结构C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆