为什么C++局部数组变量地址间隔是16字节的倍数? 5C

Linux环境下,使用g++编译,发现C++局部数组变量地址间隔是16字节的倍数,为什么呢?有什么办法可以控制间隔的大小。

char str1[] = "abcd";
char str2[2];
printf("address_str1= %p\n",str1);
printf("address_str2= %p\n",str2);

结果是:
address_str1= 0x7ffff0554e20
address_str2= 0x7ffff0554e10

8个回答

应该有以下几个目的
一个是防止偶然性的数组越界造成的损害,因为大部分的数组越界发生在数组之后1、2个下标的地方。将将好分配内存,会导致出错概率增大很多。
一个是提高性能,提高性能有两个,一个是字节对齐,可以提高内存访问的效率。对于双通道内存来说,它一次性可以访问128b/256b的内存,也就是16/32字节,那么如果数据不对齐,就需要额外的时钟周期访问,就很低效。
还有就是减少重新分配内存导致的内存碎片。

K346K346
Dablelv 回复caozhy: 请问双通道内存指的是什么,为什么可以一次性访问128b/256b的内存
一年多之前 回复
caozhy
贵阳老马马善福专门编写代码的老马就是我! 回复K346K346: 是和编译器和编译器配置有关。我说的是目的,你说的是现象,不矛盾。
一年多之前 回复
K346K346
Dablelv 发现这个和编译器有关,windows下,上面的代码编译之后发现数据间隔是32字节。
一年多之前 回复

这个在计算机组成原理里面叫地址对齐,地址是16字节的,那么16字节的倍数的对齐就方便了计算机去寻址。
而且你不能固话的理解他是16字节的倍数,地址的分配是编译器行为。

address_str1= 0x7ffcdede0a2b
address_str2= 0x7ffcdede0a29

实际上指针代表的是寻地址,指针长度实际上和最大的寻址长度是有关系的,32位机的最大寻址长度为4Byte,所以实际上sizeof(p)就是指针p的地址,那肯定是4呀!但是8位单片机,16位单片机和64位单片机就不一样了,如果8位的单片机用8位的编译器编译,sizeof(p)必是1。我们有时候发现为啥我们用64位的电脑编译,发现sizeof(p)=4呢,因为我们用的编译器是32位的。

这样做有什么意义吗?局部变量内存分配时自动的,如果你把str1定义的非常长,那么str1和str2的地址就会离得很远,可是这有什么意义呢?

shihengzhen101
AlbertS 回复K346K346: 16的倍数应该是为了字节对齐,加快内存访问速度
一年多之前 回复
K346K346
Dablelv 离得很远,确实如此,但是有个规律,是16的倍数?编译器这么做,还是有内在的原因的。
一年多之前 回复

你改变str1的字符串长度试试看,而且这个是和编译器有一定关系的

这个是与编译器甚至与操作系统有关系的。不一定都是这样了。
作为程序员没必要研究这个了。

我们只要知道除开基本变量,其它类型的变量编译器都会帮我们自动补齐,并且补齐的位数是与编译器选定的对齐位数有关即可。

也就是说我们只要知道sizeof(struct)到底是多大,不能傻傻分不清楚。
无需知道,struct1与struct2中间的地址偏移了多少,这个是不一定的了。

为什么要控制间隔呢?这是栈上的数据,编译器根据运行时环境定的,16字节是为了cache line对齐,提高性能。

之所以是16字节是因为你把str1数组的元素定义成了4个,每个地址占4个字节,数组的的地址又是连续的,所以两个数组的首地址想差16

第一,这个地址一般都是一个int类型的数据,不同的电脑上对应的int长度也可能有所不同(short至少16位,int至少与short一样长);
第二,这两个char类型的数组在内存中的位置是系统自动分配的,此时系统给他们分配了相邻的位置(也就是刚好做了邻居),这只能说是凑巧,因为系统也可能将A数组放在A处,而B数组却放在距离A很远的地方。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!