体系结构相关(面经)

1、什么是内存对齐以及为什么要内存对齐?

内存对齐:编译器将程序中的每个“数据单元”安排在适当的位置上。

简单理解:按照某种规则将我们定义的结构体成员放在合适的地址偏移位置上存储。

举一个例子:

//32位系统
#include<iostream>
using namespace std;
 
struct{
    int x;
    char y;
}s;
 
int main()
{
    cout << sizeof(s) << endl; 
    return 0;
}

问题:上述代码的输出是多少?

答案:8

为什么要额外的3字节去填充这个结构体?一个原本5字节的结构现在变成8 字节,几乎扩大了 2 倍的存储空间,这样的空间开销是否值得?又是什么样的原因导致这样的设计?

内存对齐的原因

1.内存以字节为单位

    内存是以字节为单位存储,但是处理器并不会按照一个字节为单位去存取内存。处理器存取内存是块为单位,块的大小可以是2,4,8,16字节大小,这样的存取单位称为内存存取粒度。如果在64位的机器上,不论CPU是要读取第0个字节还是要读取第1个字节,在硬件上传输的信号都是一样的。因为它都会把地址0到地址7,这8个字节全部读到CPU,只是当我们是需要读取第0个字节时,丢掉后面7个字节,当我们是需要读取第1个字节,丢掉第1个和后面6个字节。所以对于计算机硬件来说,内存只能通过特定的对齐地址进行访问。

2.内存存取效率:

    从内存存取效率方面考虑,内存对齐的情况下可以提升CPU存取内存的效率。比如有一个整型变量(4 字节),现在有一块内存单元: 地址从 0~7。这个整型变量从 地址为 1 的位置开始占据了 1,2,3,4 这 4 个字节。 现在处理器需要读取这个整型变量。假设处理器是 4 字节 4 字节的读取,所以从 0 开始读读取 0,1,2,3发现并没有读完整这个变量,那么需要再读一次,读取 4,5,6,7。然后对两次读取的结果进行处理,提取出 1,2,3,4 地址的内容。需要两次访问内存,同时通过一些逻辑计算才能得到最终的结果。如果进行内存对齐,将这个整型变量放在从0开始的地址存放,那么CPU只需要一次内存读取,并且没有额外的逻辑计算。可见内存对齐之后存取的效率提升了1倍。

 总结:

通过填充字段padding使得结构体大小与机器字倍数对齐是一种常见的做法。显然内存对齐是会浪费一些空间的。但是这种空间上得浪费却可以减少存取的时间。这是典型的一种以空间换时间的做法。在内存越来越便宜的今天,这一点点的空间上的浪费就不算什么了。因为访问内存的速度对于处理来说是非常非常的慢, 内存访问速率对于现在 CPU 来说越来越跟不上, 额外的内存访问无疑是浪费 CPU的。

 

面试真题

1.C++当中一个空的结构体或者类的对象的大小是多少?

答案: 空的类或者结构体的大小是1个字节,因为C++当中每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址。

 

2.结构体成员的声明顺序会影响结构体的大小么?比如下面两个结构体A,B他们大小是多少?

struct A  // sizeof (A) == 12
{
 char b;
 int a;
 char c;
};
struct B  // sizeof (B) == 8
{
 char b;
 char c;
 int a;
};

答案:成员声明顺序会影响结构体大小。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C语言的数据结构面经主要包括C语言基础、操作系统、计算机网络、数据结构与算法、设计模式等内容。 在C语言的面经中,C++的增强特性也是常见的一部分,比如引用、类与对象、模板、智能指针等,还有STL模板库等。这些特性使得C++的使用更加便捷和安全。 此外,C++11引入了一些新特性,比如std::enable_if和SFINAE。SFINAE是Substitution failure is not an error的缩写,意思是匹配失败不是错误。简单来说,当调用模板函数时,编译器会根据传入参数推导最合适的模板函数,在这个推导过程中,如果某些模板函数的推导结果是编译无法通过的,只要有一个可以正确推导出来的模板函数,那些推导结果可能引发编译错误的模板函数并不会导致整个编译错误。 在面试中,还会涉及到指向数据成员的指针。C++中可以使用指向类成员函数的指针来调用函数,也可以使用指向类数据成员的指针来访问数据成员。 多线程也是面试中常见的一个话题,关于多线程的问题,需要考虑线程安全性。在C++中,需要采取一些措施来保证线程安全,比如使用互斥锁、条件变量等。 综上所述,C语言的数据结构面经主要围绕C语言基础、操作系统、计算机网络、数据结构与算法、设计模式等内容展开,并且会涉及到C++的一些增强特性,以及指向数据成员的指针和多线程的相关知识。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [C++开发工程师面经总结](https://blog.csdn.net/Arcofcosmos/article/details/127156504)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [2020秋招_C++基础、数据结构基础面经记录](https://blog.csdn.net/XindaBlack/article/details/107120742)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇湘夜雨~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值