对于共用体,内存对齐后,用数组操作多余分配的字节是否合法?

问题:

该共用体理论上在内存中只占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数组 越界 非法操作内存,所以程序直接死亡;

上述结果证明,内存对齐分配多余的字节是合法的,是可以访问和读写改变的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值