Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将字符数组(或某些字节)视为结构对象。它是如何工作的?_C++_Struct_Memory Alignment_Reinterpret Cast - Fatal编程技术网

C++ 将字符数组(或某些字节)视为结构对象。它是如何工作的?

C++ 将字符数组(或某些字节)视为结构对象。它是如何工作的?,c++,struct,memory-alignment,reinterpret-cast,C++,Struct,Memory Alignment,Reinterpret Cast,我见过将字符数组作为结构/类处理并直接对其进行操作的技术。请参见以下伪示例: Struct Container { char e1; short e2; int e3; Class4 e4; Class5 e5; // more... } char *msg = char[SOME_SIZE]; // Fill up the msg with some bit stream. // Then we treat the char array as

我见过将字符数组作为结构/类处理并直接对其进行操作的技术。请参见以下伪示例:

Struct Container {
    char e1;
    short e2;
    int e3;
    Class4 e4;
    Class5 e5;
    // more...
}

char *msg = char[SOME_SIZE];
// Fill up the msg with some bit stream.

// Then we treat the char array as struct.
Container *ctn = reinterpret_cast<Container *>(msg);
int v3 = ntohl( ctn.e3 );
short v4 = ctn.e4.toValue();    // Call methods of Class4 to output proper value.
int v5 = ctn.e5.toValue();
Struct容器{
字符e1;
短e2;
INTE3;
第4类e4;
第5类e5;
//更多。。。
}
char*msg=char[SOME_SIZE];
//用一些比特流填充msg。
//然后我们将char数组视为struct。
容器*ctn=重新解释铸件(味精);
int v3=ntohl(ctn.e3);
short v4=ctn.e4.toValue();//调用Class4的方法以输出正确的值。
intv5=ctn.e5.toValue();
问题是这项技术什么时候能起作用?i、 e.对结构及其成员的要求。显然,最大的问题是容器何时具有结构/类对象,如e4和e5。顺便说一句,我想在Linux中使用它

我想知道内存对齐在这种使用中何时起作用

如果有好文章可供参考,我将不胜感激

关于本的评论。我看到的用例是从套接字接收消息,在套接字中消息格式定义良好。我想这里的动机是需要速度。使用这种技术,我们不需要复制任何字段来将它们填充到结构中,只需直接使用它们。这样可以节省一些内存和CPU时间

我在想我们该如何处理路线

问题是这项技术什么时候能起作用

当字符缓冲区保存正确对齐的有效
容器
对象(这意味着所有数据成员和基也必须递归有效)时(即地址是
(容器)
的倍数),它就会工作

通常,在那里获取有效对象意味着使用placement
new
,但在多进程代码中——当通过IPC机制接收/访问对象时——您应该警惕以下情况:

  • 引用或指针(包括指向虚拟分派表的指针),因为它们通常不会被设置为您自己应用程序的虚拟地址空间中有意义的内容(除非其他进程(例如,将内存映射段固定在同一硬编码虚拟地址处)

  • 进程中可能无效的文件/套接字描述符、资源ID、引用计数等

  • endianness、32位与64位大小、系统之间的对齐和填充差异

  • 清理操作,例如从观察者或管理对象取消对象注册,如果对象不是在流程中实际创建的,则这些操作没有意义


大多数都是常识——在天平的吊舱端很容易,但很少值得(过度序列化/反序列化)在复杂对象端。

它们都是字节。如果不假设大小和对齐方式,这将起作用。但千万不要这样做。尤其不要寻找它的用途。类型系统存在是有原因的。“它是如何工作的?”事实并非如此。正式而言,如果它能起作用,那只是因为你的编译器不会被恶意利用这种转换的方式所困扰:你更容易耸耸肩,为你(认为你)想要的东西服务,生命周期和对齐都是该死的。唯一定义的将一堆
char
s转换为对象的方法是(a)确保它是可复制的,(B)分配一个实例(生命周期、对齐)和(C)
memcpy()
char
s给它。在允许的平台上,好的编译器可以将其优化为与你做了可怕的转换一样的代码,但不会用UB污染你的程序