我的问题是我们用填充来对齐结构。
typedef struct structb_tag
{
char c;
int i;
} structb_t;
这里我们使用8个字节。为什么我们不能使用那么多的3个字节?
答案 0 :(得分:3)
为什么我们不能使用3个字节
你可以。
为此,请测量实现为struct
分配的大小,然后使其成为一个联合,添加一个完全符合测量大小的char数组,然后就可以了。
假设这个
typedef struct structb_tag
{
char c;
int i;
} structb_t;
使用八个字节创建,sizeof (structb_t)
计算为8
,将其更改为以下
typedef union unionb_tag
{
char bytes[8];
struct
{
char c;
int i;
} structb;
}
在可移植性和稳健性方面更可靠的是:
typedef union unionb_tag
{
struct structb_tag
{
char c;
int i;
} structb;
char bytes[sizeof (struct structb_tag)];
}
答案 1 :(得分:1)
如果你正在使用GCC并且空间对你而言是最重要的而不是速度(填充提供)你只能请求编译器不进行填充,struct __attribute__((__packed__)) mystruct
,填充是编译器的方式对齐自然界中的结构以便更快地访问。
答案 2 :(得分:0)
你总是可以把结构指针转换成字节指针并访问该结构的任何字节。
这是危险的方法。
答案 3 :(得分:0)
填充是依赖于实现的,它不是由标准定义的,你不能不使用它们,因为没有办法引用填充字节。
答案 4 :(得分:0)
是的,你可以。
container-fluid
答案 5 :(得分:0)
简而言之,我们可以使用这三个字节。
我们需要3个字节填充的原因是用于内存使用优化,因此编译器将帮助我们在c和i之间添加间隙。所以当你使用
时typedef struct structb_tag
{
char c;
int i;
} structb_t;
实际上
typedef struct structb_tag
{
char c;
char[3] unseen_members;
int i;
} structb_t;
访问这些看不见的成员不会导致任何分段错误。从操作系统的角度来看,显式地由程序员声明并由隐式编译器声明的成员之间没有区别。
#include <stdio.h>
#include <string.h>
typedef struct Test {
char c;
int i;
} MyTest;
int main() {
MyTest my_test;
memset(&my_test, 0, sizeof(my_test));
my_test.c = 1;
int* int_ptr = (int *)&my_test.c;
printf("Size of my_test is %lu\n", sizeof(my_test));
printf("Value of my_test.c(char) is %d\n", my_test.c);
printf("Value of my_test.c(int) is %d\n", *int_ptr);
return 0;
}
这给出了:
Size of my_test is 8
Value of my_test.c(char) is 1
Value of my_test.c(int) is 1
答案 6 :(得分:0)
我们可以使用指向该结构的指针访问结构中的任何字节,并将该指针强制转换为(char *),如果我们相应地增加该指针,那么我们可以访问任何字节,但这不是很好的编程技巧。结构用一些额外的字节填充,这样程序的执行就会变得更快。