我正在ARM上进行编程,并且具有以下代码段(在C语言中):
struct data {
int x;
char y[640];
};
unsigned int offset = 819202;
char *buf; // buf is assigned an address elsewhere in the code
struct data * testdata = (struct data *)(buf + offset)
我收到以下编译错误:
错误:强制类型转换增加了目标类型[-Werror = cast-align]的必需对齐方式
testdata
指针需要指向包含struct data
类型的数据数组的内存部分。因此,我需要一个指针,以便以后可以将索引应用于testdata
。偏移在程序中进行了硬编码。 buf
从另一个进程作为共享内存接收。
例如,稍后在代码中我有:
testdata[index].x = 100;
我已经看到了一些关于SO的示例,但是我不确定处理此问题的正确方法是什么。有什么建议吗?
答案 0 :(得分:3)
当您尝试从对齐方式较小的类型转换为对齐方式较大的类型时,会触发cast-align
警告。在这种情况下,您从一个char
对齐1和一个struct data
(因为它包含int
)到对齐4(假设int
是4个字节)的情况下
使用memcpy
从缓冲区复制到该结构的实例,而不是将结构的指针指向字符数组。
struct data testdata;
memcpy(&testdata, buf + offset, sizeof(testdata));
答案 1 :(得分:1)
由于buf
是指向char
的指针,所以当您写(struct data *) (buf + offset)
时,您说的是“将此指针指向某个字符,并将其变为指向struct data
的指针。 ”。但是,struct data
必须与四个字节 1 的倍数对齐,但是您的buf+offset
可以具有任何对齐方式。如果buf+offset
的对齐方式错误,则不能成为指向struct data
的正确指针,并且编译器会为您提供有关此问题的建议。
解决方案是确保您有一个对齐的地址,可用作指向struct data
的指针。做到这一点的两种方法是:
struct data
或struct data MyData;
一样定义一个或多个struct data MyArray[10];
对象。struct data
一样,为struct data *MyPointer = malloc(SomeNumber * sizeof *MyPointer);
对象分配内存。通过上述任何一种,编译器将确保为struct data
对象正确对齐内存。前者通常仅用于立即处理struct data
然后丢弃它-它不会产生可以从函数返回的对象。当您要从函数返回结果struct data
时,可以使用后者。
一旦有了这些struct data
对象,就需要将数据放入其中。最好将数据直接读入其中,而不是读到buf
中。但是,如果您的软件设计不方便这样做,则可以使用以下一种方法将数据从buf
复制到struct data
对象中:
memcpy(&MyData, buf+offset, sizeof MyData);
memcpy(MyArray, buf+offset, sizeof MyArray);
memcpy(MyPointer, buf+offset, SomeNumber * sizeof *MyPointer);
1 对于包含int
的结构,典型值为4,在此示例中假定为4。由于编译器消息,我们知道对齐要求大于一。