一套关于 内存对齐 的C#面试题,做错的人很多!

这是一套朋友公司的面试题,挺有意思分享一下。

题目:判断下面的 Location1Location2 的结构体大小各是多少?

public struct Location1{public int X;public int Y;public long Z;}public struct Location2{public int X;public long Y;public int Z;}

据反馈 90% 的人说一样大,毕竟从代码看仅仅做了一次 YZ 顺序的交换,那真的是这样吗?可以用 windbg 调试下就好了。

完整代码代码如下:

namespace ConsoleApp2
{class Program{static void Main(string[] args){Location1 location1;Location2 location2;location1.X = 10;location1.Y = 11;location1.Z = 12;location2.X = 10;location2.Y = 11;location2.Z = 12;Debugger.Break();}}public struct Location1{public int X;public int Y;public long Z;}public struct Location2{public int X;public long Z;public int Y;}
}

windbg 输出结果如下:

0:000> !clrstack -a
OS Thread Id: 0x1750 (0)Child SP               IP Call Site
00000000007fef68 00007ff9a84b9ad2 [HelperMethodFrame: 00000000007fef68] System.Diagnostics.Debugger.BreakInternal()
00000000007ff050 00007ff989c0f5ee System.Diagnostics.Debugger.Break()00000000007ff0a0 00007ff92db5090b ConsoleApp2.Program.Main(System.String[]) [D:\net5\ConsoleApp4\ConsoleApp2\Program.cs @ 26]PARAMETERS:args (0x00000000007ff110) = 0x0000000003492cf0LOCALS:0x00000000007ff0e0 = 0x0000000b0000000a0x00000000007ff0c8 = 0x000000000000000a00000000007ff2f8 00007ff98d086913 [GCFrame: 00000000007ff2f8] 
0:000> dp 0x00000000007ff0c8
00000000`007ff0c8  00000000`0000000a 00000000`0000000c
00000000`007ff0d8  00000000`0000000b 0000000b`0000000a
00000000`007ff0e8  00000000`0000000c 00000000`007ff1f8

由于 是从大到小生长的,所以用 dp 命令的时候, location2 是排在 location1 的前方,可以清楚的看到

  1. location2: 000000000000000a 000000000000000c 000000000000000b 很明显它的 size=3*8=24byte

  2. location1: 0000000b0000000a 000000000000000c 它的 size=2*8=16byte

那为什么会差 8byte 呢?如果有熟悉 C/C++ 的朋友这时候应该知道,其实就是 内存对齐 ,为什么会出现 内存对齐 ?我们知道,内存是按照 byte 编址的,也就是一个地址存放一个byte,但cpu可不是这么玩的,它的一次读取数是根据 地址总线 来的,目前我们 cpu 基本都是 64根数据总线,也就是一次性可以读取 8个byte

为了能够让 cpu 读取效率更高,编译器会适当的进行 padding 操作,目的就是 按8 对齐,如果不对齐的话,cpu可能就会出现读不全,也就导致必须至少两次才能读取完毕的情况,肯定会影响 cpu 效率的,还有一个原因是:有些机器必须对齐访问,否则就会异常,所以编译器为了更好的平台移植性,只能对齐啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pythonweb服务器怎么让别人访问_Django配置让其他电脑访问网站

其实在Django 带有一个内建的轻量级 Web 服务器,可供站点开发过程中使用。我们提供这个服务器是为了让你快速开发站点,也就是说在准备发布产品之前,无需进行产品级 Web 服务器(比如 Apache)的配置工作。 但是实际开发中…

python3-day4(装饰器)

一.基本 第一波 #### def foo():print foofoo #表示是函数 foo() #表示执行foo函数#### 第二波 #### def foo():print foofoo lambda x: x 1foo() # 执行下面的lambda表达式,而不再是原来的foo函数,因为函数 foo 被重新定义了二.example #一个…

【C语言简单说】二:第一个C语言程序详解(3)

如有错误请给与纠正… 注:注意我们每一行代码后面的分号表示我们一句代码的结束,就像我们在写文字的时候的标点符号,一个句号表示一句话的结尾。 上一个教程只说明了第一个C语言程序源码中的main(其实等于没说)&…

【转载】关于测试人员的职业发展

近期由于项目组人手不够,需要招聘一些测试人员。本周及上周陆陆续续面试了十多个应征者,工作年限在2年~9年之间,但无一满意。期间,种种感叹,回想起去年面试六十余人仅有3人满足要求,如有鲠在喉,…

python之闭包

1 闭包概念 绑定了函数内部引用的所有变量,把它引用的东西都放在一个上下文中“包”了起来 2 闭包的Demo理解 需求:比如我们要实现2个函数,每个函数有个参数,然后现在需要实现这2个函数参数的相加功能 1) 不用闭包python普通实现 #!/usr/bin/env pythondef plus…

C#求一元二次方程的根经典案例程序

目 录 1. 界面设计 2. C#源程序 1. 界面设计 界面说明: 输入一元二次方程的二次项、一次项及常数项,这样的话对应的一元二次方程表达式就确定了,点击【计算】,即可计算出该一元二次方程的根。 2. C#源程序 using System; using System.Collections.Generic; using S…

pythonrequests说明_解决Python requests 报错方法集锦

python版本和ssl版本都会导致 requests在请求https网站时候会出一些错误,最好使用新版本。 1 Python2.6x use requests 一台老Centos机器上跑着古老的应用,加了一个新模块之后报错 报错 InsecurePlatformWarning: A true SSLContext object is not avail…

centos6,7的启动流程

CentOS 6 系统启动流程:POST --> BootSequence(BIOS) --> Bootloader --> kernel [-->ramfs] -->rootfs(ro) --> /sbin/init --> 设定默认运行级别 --> 系统初始化 --> 可以并行执行ctrlaltdel热键功能定义,系统服务的开启和…

微软是如何解决 PC 端程序多开问题的

前言在公众号上看到一篇文章《C#中解决PC端程序多开的问题》。该文作者是通过创建互斥锁Mutex实现的:bool mutexCreated; var mutex new Mutex(true, "MyApp", out mutexCreated); if (mutexCreated) {Application.Run(new Form1()); } else {MessageBox.Show("…

java中inputstream_java中InputStream String

Java 中获取输入流时,有时候须要将输入流转成String,以便获取当中的内容 ,以下总结一下 InputStream 转成String 的方式方法1:public String convertStreamToString(InputStream is) {BufferedReader reader new BufferedReader(new InputSt…

【C语言简单说】三:整数变量和输出扩展(1)

唔!经历之前眼瞎的教程之后,现在我继续的眼瞎着写接下来的章节… 注:注意我们每一行代码后面的分号表示我们一句代码的结束,就像我们在写文字的时候的标点符号,一个句号表示一句话的结尾。 注:我们printf…

做程序员的纠结在哪里

做程序员的纠结在于,人们与计算机之间的沟通的鸿沟现在交给了程序员来填。 好的程序员,必然有一面是在用0和1的模式来思考问题。 现在有很多职位也挂了程序员的名字。 比如比如数据分析师,说到底,如果你不写程序,应该称…

磁盘和文件系统管理一

主要掌握规划硬盘中的分区,创建文件系统,挂载卸载文件系统。学会添加并进行分区,学会创建并挂载文件系统。 检测并确认新硬盘 fdisk –l [磁盘设备] 规划磁盘中的分区fdisk [磁盘设备] 用途:在交互是的操作环境中管理磁盘分区 交…

JavaScript面向对象编程笔记

<!DOCTYPE html> <html> <head><title>面向对象编程</title><script type"text/javascript">var person {};//或者这样&#xff1a;var person new Object();person.name "张三";person.age 20;//函数充当属性&a…

C和指针之memmove函数 memcpy函数 strcspn函数 strspn函数 strrstr函数实现

1 memmove函数的实现 #include <stdio.h> #include <string.h>void* my_memmove(void*dest, const void*src, size_t len) { char *pdest = (char *)dest; const char* psrc = (char *)src; if ((psrc < pdest) && (pdest < psrc + len)) {…

NodeJS-queryString

无论是前端还是后端&#xff0c;经常出现的应用场景是URL中参数的处理。nodeJS的queryString模块提供了一些处理 query strings 的工具。本文将详细介绍nodeJS中的queryStringvar querystring require(querystring);/*{ unescapeBuffer: [Function],unescape: [Function: qsUn…

ASP.NET和ASP.NETCore多环境配置对比

前言多环境配置应该都很熟悉了&#xff0c;最为常见的便是Debug和Release&#xff0c;例如下图是新建的一个asp.net项目&#xff0c;配置文件展开共有三个文件组成据我所知&#xff0c;大多公司从来没编辑过Web.Debug.config和Web.Release.config&#xff0c;一个Web.config文件…

d类功放芯片_应用于无滤波级D类音频功放的新型死区时间控制系统

在音频功率放大领域&#xff0c;由于D类音频功率放大器是基于脉冲宽度调制技术的开关放大器[1-4]&#xff0c;用作放大的功率管几乎总是处于或者完全导通或者完全截止的状态&#xff0c;因此其功率损耗比传统的线性放大器小得多&#xff0c;这使得其效率非常高&#xff0c;符合…

java 字节序列_java – 这个线程安全的字节序列生成器有什么问题?

我需要一个字节生成器,它将生成从Byte.MIN_VALUE到Byte.MAX_VALUE的值.当它达到MAX_VALUE时,它应该从MIN_VALUE重新开始.我使用AtomicInteger编写了代码(见下文);但是,如果同时访问并且如果使用Thread.sleep()人为地减慢了代码,那么代码似乎没有正常运行(如果没有睡眠,它运行正…

【C语言简单说】三:整数变量和输出扩展(2)

尼玛。。。简直蛋了个翔。。。 没保存&#xff0c;&#xff0c;&#xff0c;&#xff0c; ( E___E ) 念昏了头 注&#xff1a;注意我们每一行代码后面的分号表示我们一句代码的结束&#xff0c;就像我们在写文字的时候的标点符号&#xff0c;一个句号表示一句话的结尾。 注…