sizeof(char *) = 8——C语言中的数据长度、结构体及内存对齐

本文探讨了在不同系统环境下,如xshell与Visual C++,sizeof(char *)等数据类型长度的差异,揭示了这些差异源于系统位数与编译器的影响。在64位系统中,指针占用8字节,而在32位系统中则是4字节。同时,文章提醒开发者注意结构体中数据类型的内存对齐问题以及在不同系统下long与指针类型的使用细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天同样一段代码在xshell上跑和visual c++上跑得到不一样的结果:


sizeof(char *) = 8 //linux

sizeof(char *) = 4 //windows


原因是和系统及编译器有关。

64位系统的寻址空间为2^64,保存一个指针需要64bit即8字节;

32位系统的寻址空间为2^32,保存一个指针需要32bit即4字节;

故以上差别可以用来判断系统是多少位的。



2、不同系统下其他数据类型的差别

在32位系统中,sizeof(long) = 4;sizeof(void *) = 4;

在64位系统中,sizeof(long) = 8;sizeof(void *) = 8;

在两个系统中,其他的数据类型基本一致,如sizeof(int) = 8;

另外在64位系统下long使用%ld,指针使用%p。若用%x打印一个地址,只会显示低4字节的内容。还需注意long与int转换时的截断,以及不要相互赋值。不要使用指针来存放 int 类型的值。例如:

int *ptr;
int i;
ptr = (int *) i;

在开发中要牢记long和指针类型的长度!

更多详情参见   32位与64位下各类型长度对比



3、结构体

struct score
{
	int a;
	int b;
	int c;
};

struct score s;		// 3个学生的成绩,结构体的方式
int *p =(int *)&s;
s.a = 12;		// 编译器在内部还是转成指针式访问 int *p =(int *)&s;  *(p+0) = 12;
s.b = 44;		// int *p =(int *)&s; *(p+1) = 44;
s.c = 64;		// int *p =(int *)&s; *(p+2) = 64;



4、结构体内存的对齐

参考在64位系统以及64位编译器下字节对齐----阿里巴巴2015实习生笔试题


5、取消内存对其访问__attribute__((packed))

__attribute__关键字主要是用来在函数或数据声明中设置其属性。GNU C的一大特色就是__attribute__机制。__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。

函数属性:函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。__attribute__机制也很容易同非GNU应用程序做到兼容之功效。
给函数赋给属性的主要目的在于让编译器进行优化。如函数声明中的__attribute__((noreturn)),就是告诉编译器这个函数不会返回给调用者,以便编译器在优化时去掉不必要的函数返回代码。


__attribute__语法格式为
__attribute__ ((attribute-list)) 其位置约束为:放于声明的尾部“;”之前。


packed是类型属性(Type Attribute)的一个参数,使用packed可以减小对象占用的空间。需要注意的是,attribute属性的效力与你的连接器也有关,如果你的连接器最大只支持16字节对齐,那么你此时定义32字节对齐也是无济于事的。
使用该属性对struct或者union类型进行定义,设定其类型的每一个变量的内存约束。当用在enum类型定义时,暗示了应该使用最小完整的类型(it indicates that the smallest integral type should be used)。
__attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法。这个功能是跟操作系统没关系,跟编译器有关,gcc编译器不是紧凑模式的,我在windows下,用vc的编译器也不是紧凑的,用tc的编译器就是紧凑的。

【例】下面的例子中,my-packed-struct类型的变量数组中的值会紧凑在一起,但内部成员变量中的结构体s不会被“pack”,如果希望内部的成员变量也被packed的话,my-unpacked-struct也需要使用packed进行相应的约束。
struct my_unpacked_struct
{
     char c;
     int i;
};
         
struct my_packed_struct
{
     char c;
     int i;
     struct my_unpacked_struct s;
}__attribute__ ((__packed__));


__attribute__ ((aligned(4))); 表示4字节对齐

参考:__attribute__((packed))详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值