在下面的代码中,我试图在原始内存缓冲区中存储一个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);
我得到一个段错误
。
两个问题:
一个。 Thing* thing_ptr = (Thing*) buffer[0];
有什么问题?为什么会引发错误?
B.段错误的原因是什么?
最佳答案
线
Thing* thing_ptr = (Thing*) buffer[0];
不正确。
变量 buffer
是一个 uint8_t *
,所以 buffer[0]
是一个 uint8_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]
警告表示您正在从不同大小的整数类型转换为指针。这种类型的转换通常没有意义。
出现此类警告的原因之一是为了防止出现类似您遇到的问题。
您的版本导致段错误,因为您解释了 uint8_t
值 buffer[0]
(可能是 0
或 80
,取决于字节序)作为指针。这可能是个人计算机上的无效指针,取消引用它会导致您的平台出现段错误。
关于c - 从内存缓冲区读取结构会引发编译器错误和段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57595041/