在下面的代码中,我试图将struct存储在原始内存缓冲区中。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

typedef struct {
  int a;
} Thing;

int main(void) {
  uint8_t* buffer = malloc(sizeof(Thing) * 200);

  Thing thing;
  thing.a = 80;

  memcpy(buffer, &thing, sizeof(Thing));

  Thing* thing_ptr = (Thing*) buffer[0];

  return 0;
}

但是,我收到以下编译器警告:
warning: cast to 'Thing *' from smaller integer type
      'uint8_t' (aka 'unsigned char') [-Wint-to-pointer-cast]
      Thing* thing_ptr = (Thing*) buffer[0]

另外,当我试图在最后解引用thing_ptr时:
printf("%d\n", thing_ptr->a);

我得到一个segmentation fault
两个问题:
A.Thing* thing_ptr = (Thing*) buffer[0];怎么了?为什么会引发错误?
B.segfault的原因是什么?

最佳答案

线路

Thing* thing_ptr = (Thing*) buffer[0];

不正确。
变量buffer是auint8_t *,因此buffer[0]是auint8_t。在这种情况下,buffer[0]等同于*buffer
有两种选择:
您可以取buffer[0]的地址:
Thing* thing_ptr = (Thing*) &buffer[0];

在这种情况下,这没有多大意义,尽管它可以澄清意图在其他一些情况下。
在我看来,更好的选择是放弃[0]
Thing* thing_ptr = (Thing*) buffer;

这清楚地表明您正在将buffer中的值从类型uint8_t *转换为Thing *
[-Wint-to-pointer-cast]警告表示您正在从不同大小的整数类型转换到指针。这种类型的演员通常没有意义。
这种警告存在的原因之一是防止像你所经历的那样的问题。
您的版本会导致segfault,因为您将uint8_tbuffer[0](可能是080,取决于endianness)解释为指针。这可能是个人计算机上的无效指针,取消对它的引用会导致平台上出现segfault。

关于c - 从内存缓冲区读取结构会引发编译器错误和segfault,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57595041/

10-11 22:57
查看更多