关于如何判断结构体的大小和部分内存函数的使用与实现

文章讨论了结构体中成员对齐数如何影响其大小,以VS为例,解释了为什么具有相同成员的结构体大小可能不同。同时介绍了memcpy和memmove函数,指出memcpy的限制及其与memmove在处理内存重叠时的区别。
摘要由CSDN通过智能技术生成

这两个结构体中的成员都是一样的,那么他们的大小是否都一样呢?其实不一样,S的大小为12个字节,而T却是8个字节。但是为什么呢?那是因为有着对齐数的存在,这就导致它们之间的大小不同。

每个成员变量都有相应的对齐数,其值等于该成员自身的大小与编译器默认对齐数之间较小的一个。知道对齐数的概念后,我们就可以计算结构体的大小了,首先我们得知道vs的对齐数为8,然后我们让它与结构体成员比较,如S,a的大小为1,比vs的小,所以它的对齐数为1,其次b的大小为4,同样比vs小,所以对齐数为4,同理c的对齐数为1,因为有着对齐数,所以我们不能单纯的将它们全部相加,我们可以以把它想象成盖房子,第一个成员我们将它放置在最底层,第二个成员我们就得运用到它的对齐数了,我们不得不把它放在它对齐数的整数倍上去,这就不可避免的会造成中间会有空层,(至于为什么会放在它的整数倍而不是两者紧密接触,我们等下在说),如S,第一层放a,第二层要放b,但是因为我们要放到他的整数倍对齐数,所以我们要将他放在第五层(1,2,3,4层相加刚好是他的一倍,至于为什么不放在他的两倍之类的,我想可能是为了避免无意义的空间浪费),而b又是4个字节,所以它一个独占后面4层(5,6,7,8),此时房子已经盖了8层了,后面的c的对齐数是1,那么它可以直接和b相邻(第9层,毕竟1的倍数可以是任意数嘛),这么算也才9层,哪来的12层呢?别急,还有最后一步,我们得用结构体中的成员的最大对齐数与编译器默认对齐数进行比较,然后选出最小的对齐数,结构体的层高要符合这个对齐数的整数倍,不然属于违法建筑,a,b,c中的最大对齐数是b的4,而vs的是8,因此我们的层高要是4的整数倍,而现在只有9层,所以我们得加盖3层,就变成12层了,所以S的大小为12个字节,如果成员中有数组,我们只需将他看成是数组元素全部变成结构体成员(如int arr【2】看成两个int的结构体成员),同理我们也可以有样学样把T的大小算出来,由此我们可以得出,先让大字节的成员放在最前面有利于节省空间,但设置对齐数却要浪费空间,为什么呢?因为这样可以增加效率,我们要避免的是无意义的浪费,但是可以用空间换时间。

  memcpy与strcpy的作用差不多,不过memcpy的作用范围更大,

void *memcpy(void *str1, const void *str2, size_t n)
  • str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
  • str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
  • n -- 要被复制的字节数。

这些大家都懂,我们直接开始写一个自己的memcpy

 怎么样?是不是很简单,不过这个是有缺陷的,如果str1在str2的后面的话,那么会导致复制的内容与想要的结果不同,因此这也就产生了另一个函数memmove,它的参数和memcpy一样,返回值也一样,与memcpy不同的是它可以解决重合的问题,我们同样也可以写一个自己的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值