问题:
该共用体理论上在内存中只占5字节,但是经过内存对齐后,实际会占8字节,
,那么当我越界访问数组下标为6,7,8且越界赋值的时候,程序是否会报错或者死亡呢?union dy
{
unsigned char a[5];
int b;
}dy1;经过验证:内存对齐后,多出来的三个字节,我的字符数组越界访问和赋值并不会让程序崩溃;
说明了对齐后的多分配的字节,是合法的内存,是可以操作的。
代码展示:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//共用体内存对齐后,多余出来的内存我能操作使用嘛?
union dy
{
unsigned char a[5];
int b;
}dy1;
int main(int argc, const char *argv[])
{
//普通数组用于和共用体中的数组进行对比,看执行同样的操作,是否会使得程序崩溃,对比验证
unsigned char c[5]={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xff};
//本来数组只有5个元素,共用体内存对齐后整个共用体有了八字节;
//那么多余的内存多余出来的三个字节我可以操作嘛?
dy1.a[0]=0x12;
dy1.a[1]=0x34;
dy1.a[2]=0x56;
dy1.a[3]=0x78;
dy1.a[4]=0x9a;
dy1.a[5]=0xbc;
dy1.a[6]=0xde;
dy1.a[7]=0xff;
//轮询打印数组的值
for(int ii=0;ii<8;ii++)
{
printf("a[%d]=%#x ",ii,dy1.a[ii]);
printf("c[%d]=%#x\n",ii,c[ii]);
}
for(int ii=0;ii<8;ii++)
{
dy1.a[ii]=ii+100; //该行代码并不会报错,完全合法,所以内存对齐多出来的3字节
//共用体中的元素可以使用和修改,不会存在数组越界访问没有权限的内存的风险
// c[ii]=ii+100; //该行代码会使得程序直接死亡,操作非法内存
}
//轮询打印改变数组元素后的值
for(int ii=0;ii<8;ii++)
{
printf("a[%d]=%d ",ii,dy1.a[ii]);
printf("c[%d]=%d\n",ii,c[ii]);
}
return 0;
}
运行上述代码时,编译器会发出如下警告:
什么意思呢?他的意思是主函数中的数组c的大小为5,你赋值的数量超过了他能存放的数量,即0xbc,0xde,0xff的赋值操作都是越界赋值;这样的操作是不好的,编译器像我们发出警告,此时程序正常;
但是共用中的数组a的长度虽然也是5,但是赋值却没有警告,初步说明内存对齐后分配的多余字节是是可以使用的;
注释如上图中的代码段,运行程序,结果是:
可以看出我们对共用体中的数组a进行越界读写操作,程序正常运行,没有异常;
而我们对c数组初始化越界赋值的操作,由图可以看到c[5],c[6],c[7]三个元素的值并不是0xbc,0xde,0xff; 赋值并不是成功的;
接下来我们将下图中的注释取消时,
,运行的结果为:
程序直接崩溃,因为 c数组 越界 非法操作内存,所以程序直接死亡;
上述结果证明,内存对齐分配多余的字节是合法的,是可以访问和读写改变的。