-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
480 lines (471 loc) · 87.3 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://zyrjm.xyz</id>
<title>梦想存储罐</title>
<updated>2020-08-05T07:53:58.216Z</updated>
<generator>https://github.com/jpmonette/feed</generator>
<link rel="alternate" href="https://zyrjm.xyz"/>
<link rel="self" href="https://zyrjm.xyz/atom.xml"/>
<subtitle>梦想存储罐</subtitle>
<logo>https://zyrjm.xyz/images/avatar.png</logo>
<icon>https://zyrjm.xyz/favicon.ico</icon>
<rights>All rights reserved 2020, 梦想存储罐</rights>
<entry>
<title type="html"><![CDATA[ubuntu通过Kubeadmin部署K8s集群]]></title>
<id>https://zyrjm.xyz/post/ubuntu-tong-guo-kubeadmin-bu-shu-k8s-ji-qun/</id>
<link href="https://zyrjm.xyz/post/ubuntu-tong-guo-kubeadmin-bu-shu-k8s-ji-qun/">
</link>
<updated>2020-08-01T04:43:46.000Z</updated>
<content type="html"><![CDATA[<p>通过vmware虚拟机安装两个ubuntu系统,部署k8s集群。其中要把虚拟机的网卡模式要选择为<strong>桥接模式</strong>(默认为NAT)</p>
<p>ubuntu版本:<br>
<img src="https://zyrjm.xyz/post-images/1596257304653.png" alt="" loading="lazy"></p>
<h2 id="关闭swap内存">关闭SWAP内存</h2>
<ol>
<li>
<p>k8s要求关闭电脑的<strong>swap</strong>内存,修改**/etc/fstab**文件, 注释掉红框内的两行:<br>
<img src="https://zyrjm.xyz/post-images/1596257330123.png" alt="" loading="lazy"></p>
</li>
<li>
<p>然后重启电脑reboot</p>
</li>
<li>
<p>使用命令<strong>free -m</strong>查看虚拟内存, 可以看到swap内存已经为0了<br>
<img src="https://zyrjm.xyz/post-images/1596257339805.png" alt="" loading="lazy"></p>
</li>
</ol>
<h2 id="安装和配置docker">安装和配置docker</h2>
<ol>
<li>
<p>安装docker:<code>sudo apt install docker.io</code></p>
</li>
<li>
<p>设置开机运行docker: <code>systemctl enable docker.service</code></p>
</li>
<li>
<p>docker -v 查看docker版本<br>
<img src="https://zyrjm.xyz/post-images/1596257359808.png" alt="" loading="lazy"></p>
</li>
<li>
<p>修改docker下载镜像为国内源,编辑**/etc/docker/daemon.json**:</p>
<pre><code class="language-c">sudo vim /etc/docker/daemon.json
</code></pre>
<p> 打开后输出以下内容:</p>
<pre><code class="language-c">{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com",
"https://quay-mirror.qiniu.com"
],
}
</code></pre>
</li>
<li>
<p>修改cgroups。docker用它来实现容器的隔离,cgroups是docker默认使用的方式,而k8s使用的隔离工具是systemd,如果两个隔离的方式不同的话可能引起异常,所以芭doker的也修改为systemd,在此编辑**/etc/docker/daemon.json**,添加如下内容</p>
<pre><code>"exec-opts": ["native.cgroupdriver=systemd"]
</code></pre>
</li>
</ol>
<figure data-type="image" tabindex="1"><img src="https://zyrjm.xyz/post-images/1596257378565.png" alt="" loading="lazy"></figure>
<ol start="6">
<li>
<p>重启docker</p>
<pre><code class="language-c">sudo service docker restart
</code></pre>
</li>
<li>
<p>查看cgroups的类型已经修改为了systemd</p>
</li>
</ol>
<figure data-type="image" tabindex="2"><img src="https://zyrjm.xyz/post-images/1596257387106.png" alt="" loading="lazy"></figure>
<p>为了避免每次都要sudo才能执行docker的相关操作,可以把当前用户加入docker组里:</p>
<pre><code class="language-c">sudo gpasswd -a ${USER} docker // 把当前用户加入docker用户组
newgrp - docker // 用户组切换为docker
</code></pre>
<p>之后就可以直接执行docker的相关操作了</p>
<h2 id="安装k8s">安装k8s</h2>
<p><a href="https://hub.docker.com/">安装</a>k8s主要是安装三个主要组件<code>kubelet</code>、<code>kubeadm</code>以及<code>kubectl</code>:</p>
<ul>
<li><code>kubelet</code>:k8s的核心服务</li>
<li><code>kubeadm</code>: 这个是用于快速安装 k8s 的一个集成工具,我们在<code>master1</code>和<code>worker1</code>上的 k8s 部署都将使用它来完成</li>
<li><code>kubectl</code>: k8s 的命令行工具,与k8s的交互都是通过它来完成</li>
</ul>
<p>由于某些原因,,它们的下载地址不存在了。所以我们需要用国内的镜像站来下载,也很简单,依次执行下面五条命令即可。</p>
<pre><code class="language-c"># 使得 apt 支持 ssl 传输
sudo apt install -y apt-transport-https
# 下载 gpg 密钥
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
# 添加 k8s 镜像源
sudo bash -c 'cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF'
# 更新源列表
sudo apt update
# 下载 kubectl,kubeadm以及 kubelet
sudo apt install -y kubelet kubeadm kubectl
</code></pre>
<h2 id="配置master节点">配置master节点</h2>
<ol>
<li>
<p>修改master的ip为<code>静态ip</code></p>
</li>
<li>
<p>使用<code>kubeadm init</code>命令初始化master节点:</p>
<pre><code class="language-c"># --apiserver-advertise-address对应的ip地址需要修改自己机器的地址
sudo kubeadm init --apiserver-advertise-address=192.168.1.6 --image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16
</code></pre>
<p>说明一下各个参数的含义:</p>
<ul>
<li><code>--apiserver-advertise-address</code>: k8s 中的主要服务<code>apiserver</code>的部署地址,填自己的管理节点 ip</li>
<li><code>--image-repository</code>: 拉取的 docker 镜像源,因为初始化的时候<code>kubeadm</code>会去拉 k8s 的很多组件来进行部署,所以需要指定国内镜像源,下不然会拉取不到镜像。</li>
<li><code>-pod-network-cidr</code>: 这个是 k8s 采用的节点网络,因为我们将要使用<code>flannel</code>作为 k8s 的网络,所以这里填<code>10.244.0.0/16</code>就好</li>
</ul>
</li>
<li>
<p>虽然配置了image-repository,但是依然会发现报无法拉取镜像的错误。</p>
</li>
<li>
<p>我们根据报错只能收到去docker.hub上去手动安装对应的docker镜像</p>
<figure data-type="image" tabindex="3"><img src="https://zyrjm.xyz/post-images/1596257402335.png" alt="" loading="lazy"></figure>
<p>这儿以第一个错为例可以看到是拉取<code>kube-apiserver:v1.18.6</code>的版本出错了</p>
<figure data-type="image" tabindex="4"><img src="https://zyrjm.xyz/post-images/1596257411815.png" alt="" loading="lazy"></figure>
<ul>
<li>
<p>我们去 <a href="https://hub.docker.com/">dockerhub</a>上搜索对应的镜像</p>
<figure data-type="image" tabindex="5"><img src="https://zyrjm.xyz/post-images/1596257420461.png" alt="" loading="lazy"></figure>
</li>
<li>
<p>我们选择第二个,然后在其中找到对应版本的镜像</p>
<figure data-type="image" tabindex="6"><img src="https://zyrjm.xyz/post-images/1596257427918.png" alt="" loading="lazy"></figure>
</li>
<li>
<p>复制镜像的下载地址:</p>
<figure data-type="image" tabindex="7"><img src="https://zyrjm.xyz/post-images/1596257434983.png" alt="" loading="lazy"></figure>
</li>
<li>
<p>下载镜像:<br>
<img src="https://zyrjm.xyz/post-images/1596257717962.png" alt="" loading="lazy"></p>
</li>
<li>
<p>需要对下载镜像打<code>tag</code>,关联k8s需要的镜像名字<br>
<img src="https://zyrjm.xyz/post-images/1596257457885.png" alt="" loading="lazy"></p>
</li>
</ul>
</li>
<li>
<p>对所有报错的镜像,执行同样的操作。执行<code>sudo kubeadm reset</code>重置环境,再重新执行<code>kubeadm Init</code>即可:</p>
<pre><code class="language-c">sudo kubeadm init --apiserver-advertise-address=192.168.1.6 --image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16
</code></pre>
<p>如果出现了下面的字样就表示安装成功了:</p>
</li>
</ol>
<figure data-type="image" tabindex="8"><img src="https://zyrjm.xyz/post-images/1596257471719.png" alt="" loading="lazy"></figure>
<p>红框中的<code>kubeadm join</code>指令需要复制下来,其他的节点加入集群时需要用到的指令,如果忘了就执行<code>kubeadm token create --print-join-command</code>重新生成一条。</p>
<p>如果在安装中出现了任何错误,需要执行<code>sudo kubeadm reset</code>重置环境以后,再执行上面的<code>kubeadm init</code>指令</p>
<h2 id="配置kubectl工具">配置kubectl工具</h2>
<ol>
<li>
<p>执行下面的命令</p>
<pre><code>mkdir -p ~/.kube
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
sudo chown -R `whoami`:`whoami` ~/.kube
</code></pre>
</li>
<li>
<p>测试是否可用:</p>
<pre><code>kubectl get nodes
</code></pre>
<p>如果能看到下面类似的结果就表示可以用了</p>
<figure data-type="image" tabindex="9"><img src="https://zyrjm.xyz/post-images/1596257483621.png" alt="" loading="lazy"></figure>
</li>
</ol>
<h2 id="部署-flannel-网络">部署 flannel 网络</h2>
<p><code>flannel</code>是一个专门为 k8s 设置的网络规划服务,可以让集群中的不同节点主机创建的 docker 容器都具有全集群唯一的虚拟IP地址。想要部署<code>flannel</code>的话直接执行下述命令即可:</p>
<pre><code>kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
</code></pre>
<p>由于<code>raw.githubusercontent.com</code>被墙了,所以需要现在<a href="https://www.ipaddress.com/">IpAdress.com</a>输入<code>raw.githubusercontent.com</code>查询ip地址然后添加到hosts文件</p>
<ul>
<li>
<p>查询ip</p>
<figure data-type="image" tabindex="10"><img src="https://zyrjm.xyz/post-images/1596257505307.png" alt="" loading="lazy"></figure>
</li>
<li>
<p>修改hosts文件,<code>sudo vim /etc/hosts</code>,添加查询到的ip地址</p>
<figure data-type="image" tabindex="11"><img src="https://zyrjm.xyz/post-images/1596257514487.png" alt="" loading="lazy"></figure>
</li>
</ul>
<p>如果输出了下面类似的内容,则表示安装成功:</p>
<figure data-type="image" tabindex="12"><img src="https://zyrjm.xyz/post-images/1596257523541.png" alt="" loading="lazy"></figure>
<p>至此<code>k8s的master</code>节点部署完成</p>
<h2 id="克隆一个worker的虚拟机">克隆一个worker的虚拟机</h2>
<p>woker节点,也需要安装K8s和docker相关工具,为了方便我们之间从master虚拟机克隆一台来作为node(克隆前需要先关闭虚拟机):</p>
<figure data-type="image" tabindex="13"><img src="https://zyrjm.xyz/post-images/1596257531468.png" alt="" loading="lazy"></figure>
<p>需要注意克隆类型选择<code>完整克隆</code></p>
<figure data-type="image" tabindex="14"><img src="https://zyrjm.xyz/post-images/1596257538388.png" alt="" loading="lazy"></figure>
<p>克隆成功后进入worker机器 由于master是设置的静态ip,克隆出来的虚拟机ip会有冲突,所以我们还需要修改ip地址。</p>
<h2 id="将-node-节点加入网络">将 node 节点加入网络</h2>
<ol>
<li>
<p>由于我们node节点是从master里克隆出来的,所以主机名会重复,我们需要修改主机名为node:</p>
<pre><code class="language-c">sudo hostnamectl set-hostname node
</code></pre>
<p>再使用hostname查看改动是否生效:</p>
<figure data-type="image" tabindex="15"><img src="https://zyrjm.xyz/post-images/1596257564842.png" alt="" loading="lazy"></figure>
</li>
<li>
<p>执行master节点生成的<code>kubeadm join</code>指令</p>
<pre><code>sudo kubeadm join 192.168.1.6:6443 --token purbtm.12d7g98hq3kljqof --discovery-token-ca-cert-hash sha256:c0b3f8da3ae4a668e3159716f4a821adf32166940103ac807f19d5c9df46a1e2
</code></pre>
<p>注意不要直接复制,每个机器都会不一样。</p>
<p>如果执行错误了,同样需要执行<code>kubeadm reset</code>重置,再重新执行命令</p>
<p>如果出现了下面类似的输出,就表示成功了:</p>
<figure data-type="image" tabindex="16"><img src="https://zyrjm.xyz/post-images/1596257584505.png" alt="" loading="lazy"></figure>
</li>
<li>
<p>回到master节点,执行<code>kubectl get nodes</code>查看节点情况,可以看出node已经加了节点:</p>
<figure data-type="image" tabindex="17"><img src="https://zyrjm.xyz/post-images/1596257592759.png" alt="" loading="lazy"></figure>
</li>
</ol>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[使用代理加速github]]></title>
<id>https://zyrjm.xyz/post/shi-yong-dai-li-jia-su-github/</id>
<link href="https://zyrjm.xyz/post/shi-yong-dai-li-jia-su-github/">
</link>
<updated>2020-07-27T14:55:38.000Z</updated>
<content type="html"><![CDATA[<p>因为git默认是不使用系统的代理服务器,即使我们开了梯子,git下载依然很慢,所以需要一些额外配置。这儿我们以windows下的lantern为例</p>
<h2 id="查看代理服务器">查看代理服务器</h2>
<ol>
<li>打开lantern设置<br>
<img src="https://zyrjm.xyz/post-images/1595861891781.png" alt="" loading="lazy"></li>
<li>点击设置<br>
<img src="https://zyrjm.xyz/post-images/1595861885372.png" alt="" loading="lazy"></li>
<li>点击高级设置,查看代理服务器<br>
<img src="https://zyrjm.xyz/post-images/1595861935756.png" alt="" loading="lazy"></li>
</ol>
<h2 id="git配置http代理">git配置http代理</h2>
<p>用于加速https形式的clone</p>
<ol>
<li>
<p>设置http代理 用于我们只有从github上clone时才会用到代理,从码云或者自己的git服务器时就不需要了,所以配置时加上域名</p>
<p><strong>git config --global http.https://g.nite07.org.proxy http://127.0.0.1:51462</strong><br>
<img src="https://zyrjm.xyz/post-images/1595862059482.png" alt="" loading="lazy"></p>
</li>
<li>
<p>设置配置https代理</p>
<p><strong>git config --global https.https://g.nite07.org.proxy http://127.0.0.1:51462</strong><br>
<img src="https://zyrjm.xyz/post-images/1595862066655.png" alt="" loading="lazy"></p>
</li>
<li>
<p>查看git 配置。 确认已生效</p>
<p>**git config -l **<br>
<img src="https://zyrjm.xyz/post-images/1595862097330.png" alt="" loading="lazy"></p>
</li>
<li>
<p>取消配置。如果需要取消使用unset</p>
<p><strong>git config --global --unset http.https://g.nite07.org.proxy</strong></p>
<p><strong>git config --global --unset https.https://g.nite07.org.proxy</strong></p>
</li>
</ol>
<h2 id="配置ssh代理">配置ssh代理</h2>
<p>很多时候我是通过ssh来下载代码,因此还需要为ssh配置代理</p>
<ol>
<li>
<p>编辑配置文件 vim ~/.ssh/config<br>
<img src="https://zyrjm.xyz/post-images/1595862117309.png" alt="" loading="lazy"></p>
</li>
<li>
<p>增加一个github的配置段,为连接github.com时配置lantern的sockets代理</p>
<pre><code class="language-c">Host github.com
HostName github.com
User git
ProxyCommand connect -S 127.0.0.1:51463 %h %p
</code></pre>
</li>
</ol>
<figure data-type="image" tabindex="1"><img src="https://zyrjm.xyz/post-images/1595862125982.png" alt="" loading="lazy"></figure>
<h2 id="linux下的配置">linux下的配置</h2>
<p>linux下配置整体和上面windows的相同,只是ssh代理里的<code>ProxyCommand connect -S 127.0.0.1:51463 %h %p</code>需要修改为<code>ProxyCommand nc -v -x 127.0.0.1:51463 %h %p</code></p>
<h2 id="其他梯子">其他梯子</h2>
<p>如果使用的是其他梯子原理也相同,只需要找到梯子的代理服务器地址即可</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[C语言结构体对齐]]></title>
<id>https://zyrjm.xyz/post/c-yu-yan-jie-gou-ti-dui-qi/</id>
<link href="https://zyrjm.xyz/post/c-yu-yan-jie-gou-ti-dui-qi/">
</link>
<updated>2020-07-27T13:23:59.000Z</updated>
<content type="html"><![CDATA[<h1 id="结构体内存对齐">结构体内存对齐</h1>
<ol>
<li>
<p>结构体对齐是为了提高CPU读取内存效率,防止一个数据放在两个8自己内存块中。无论是否对齐,x86-64都能正确工作。对齐的基本原则是<strong>K字节类型对象的对象起始地址必须是K的倍数</strong>:<br>
<img src="https://zyrjm.xyz/post-images/1595856553524.png" alt="" loading="lazy"></p>
</li>
<li>
<p>编译器需要在结构体中插入一些空隙来保证对齐,考虑下面的结构体:</p>
<pre><code class="language-c">struct s1 {
int i;
char c;
int j;
};
struct s1 a;
struct s1* p = &a;
</code></pre>
<p>假设p的地址为<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">x_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>:</p>
<ul>
<li><code>&p->i</code>等于结构体的地址,<code>i</code>为<code>int</code>类型它的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>等于4,所以编译器必须保证<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">x_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>是4的倍数</li>
<li><code>&p->c</code>的地址等于<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub><mo>+</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">x_p+4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8694379999999999em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span>, 它的K等于1,地址肯定是1的倍数,所以不用对齐</li>
<li><code>&p->j</code>的地址等于<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub><mo>+</mo><mn>5</mn></mrow><annotation encoding="application/x-tex">x_p+5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8694379999999999em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">5</span></span></span></span>, 它的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>是4, 地址不是4的倍数,所以需要对齐,需要补齐3个字节, 地址变为<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub><mo>+</mo><mn>8</mn></mrow><annotation encoding="application/x-tex">x_p+8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8694379999999999em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">8</span></span></span></span>, 地址是4的倍数</li>
<li>所以对齐后整个结构体的大小<code>sizeof(s1)</code>变成了12个字节</li>
</ul>
</li>
<li>
<p>结构体的尾末也需要对齐。考虑下面的结构体:</p>
<pre><code class="language-c">struct s2 {
int i;
int j;
char c;
};
struct s2 a;
struct s2* p = &;
</code></pre>
<p><code>struct s2</code>和<code>struct s1</code>相比,调换了成员<code>c</code>和<code>j</code>的顺序。假设<code>p</code>的地址为<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">x_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>, 如果按照之前的思路计算:</p>
<ul>
<li><code>&p->i</code>等于结构体的地址,<code>p->i</code>的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>等于4,所以编译器必须保证<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">x_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>是4的倍数。</li>
<li><code>&p->j</code>的地址等于<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">x_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>+4,它的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>等于4,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub><mo>+</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">x_p+4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8694379999999999em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span>肯定也是4的倍数,所以也不用对齐。</li>
<li><code>&p->c</code>的地址等于<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>p</mi></msub><mo>+</mo><mn>8</mn></mrow><annotation encoding="application/x-tex">x_p+8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8694379999999999em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">p</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">8</span></span></span></span>,它的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>等于1,地址肯定是1的倍数,所以不用对齐。</li>
<li>那么<code>sizeof(s2) = 9</code><br>
但是测试<code>sizeof(s2)</code>依然是12个字节,这是为什么呢?对于单个结构体9个字节以及能够满足对齐了,但是如果是结构体数组呢,考虑如下定义:</li>
</ul>
<pre><code class="language-c">struct s2 d[4];
</code></pre>
<p>如果不对结构体末尾进行对齐,假设d的地址位<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>d</mi></msub></mrow><annotation encoding="application/x-tex">x_d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">d</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>,首先<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>d</mi></msub></mrow><annotation encoding="application/x-tex">x_d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">d</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>肯定是4的倍数,那么d[1]的地址就是<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>d</mi></msub></mrow><annotation encoding="application/x-tex">x_d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">d</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> + <code>sizeof(s2)</code> = <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>d</mi></msub><mo>+</mo><mn>9</mn></mrow><annotation encoding="application/x-tex">x_d + 9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">d</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">9</span></span></span></span>,那么肯定不满足<code>d[i]->i</code>的对齐规则,因为它的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>是4,而<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>d</mi></msub></mrow><annotation encoding="application/x-tex">x_d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">d</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>不是4的倍数。所以<code>sizeof(s2)</code>就必须是12个字节,也就是需要在末尾补齐3个字节</p>
</li>
<li>
<p>可以看出来要满足元素开头地址是其<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>的整数倍。不仅需要填充字节还需要保证结构体的首字节地址也必须满足某些规则,也就是不单需要考虑单个结构体的情况,还需要考虑连续多个结构体的情况。为了得到更通用的规则,我们定义一个通用模型(先假设结构体元素都是简单元素):</p>
<pre><code class="language-c">// T1, T2, ..., Tk都是简单类型,非数组和结构体的复合类型
struct sc {
T1 x1;
T2 x2;
...
Tn xn;
...
}
struct sc c;
struct sc ac[N];
</code></pre>
<p>假<code>struct sc c</code>的地址位<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>c</mi></msub></mrow><annotation encoding="application/x-tex">x_c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>,任意成员<code>xn</code>相对于<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>c</mi></msub></mrow><annotation encoding="application/x-tex">x_c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的偏移位<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>,<code>Tn</code>类型的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值为<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, 结构体的大小为<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><mi>i</mi><mi>z</mi><mi>e</mi><mi>C</mi></mrow><annotation encoding="application/x-tex">SizeC</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord mathdefault">i</span><span class="mord mathdefault" style="margin-right:0.04398em;">z</span><span class="mord mathdefault">e</span><span class="mord mathdefault" style="margin-right:0.07153em;">C</span></span></span></span>, 结构体已经对齐,那么:</p>
<ul>
<li>先考虑单个结构体的情况,对于任意成员<code>xn</code>,有<code>&c.xn</code>= <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>c</mi></msub><mo>+</mo><mi>N</mi></mrow><annotation encoding="application/x-tex">x_c + N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>, 那么<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>c</mi></msub><mo>+</mo><mi>N</mi></mrow><annotation encoding="application/x-tex">x_c + N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>一定是<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的n整数倍。当<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>是0的时候,表示第一个元素的地址,也意味着<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>c</mi></msub></mrow><annotation encoding="application/x-tex">x_c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>一定是是第一个元素<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值的整数倍</li>
<li>在考虑结构体数组,对于索引为<code>i</code>的结构体<code>ac[i]</code>,其任意成员<code>xn</code>,有<code>&ac[i].xn</code> = <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>c</mi></msub><mo>+</mo><mi>i</mi><mo>∗</mo><mi>S</mi><mi>i</mi><mi>z</mi><mi>e</mi><mi>c</mi><mo>+</mo><mi>N</mi></mrow><annotation encoding="application/x-tex">x_c + i*Sizec + N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathdefault">i</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord mathdefault">i</span><span class="mord mathdefault" style="margin-right:0.04398em;">z</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>, 因为<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>x</mi><mi>c</mi></msub><mo>+</mo><mi>N</mi></mrow><annotation encoding="application/x-tex">x_c + N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">c</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>一定是<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的整数倍,所以<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>i</mi><mo>∗</mo><mi>s</mi><mi>i</mi><mi>z</mi><mi>e</mi><mi>c</mi></mrow><annotation encoding="application/x-tex">i*sizec</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathdefault">i</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathdefault">s</span><span class="mord mathdefault">i</span><span class="mord mathdefault" style="margin-right:0.04398em;">z</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span></span></span></span>也一定是<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的整数倍意味者<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><mi>i</mi><mi>z</mi><mi>e</mi><mi>c</mi></mrow><annotation encoding="application/x-tex">Sizec</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord mathdefault">i</span><span class="mord mathdefault" style="margin-right:0.04398em;">z</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span></span></span></span>也必须是<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的整数倍(<code>i=1</code>时)。因为<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>可以结构体的任意元素,所以<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><mi>i</mi><mi>z</mi><mi>e</mi><mi>c</mi></mrow><annotation encoding="application/x-tex">Sizec</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord mathdefault">i</span><span class="mord mathdefault" style="margin-right:0.04398em;">z</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span></span></span></span>必须是所有元素<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值的整数倍。而<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的取值范围是{1, 2, 4, 8},当<code>xn</code>是<code>struct sc</code>中最大的成员时,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>也是最大的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><mi>i</mi><mi>z</mi><mi>e</mi><mi>c</mi></mrow><annotation encoding="application/x-tex">Sizec</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord mathdefault">i</span><span class="mord mathdefault" style="margin-right:0.04398em;">z</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span></span></span></span>是<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的整数倍,也就意味着$ Sizec$一定是其他元素的整数倍</li>
</ul>
</li>
<li>
<p>还有一个很有意思的事情。假设下面一个结构体:</p>
<pre><code class="language-c">struct St{
char a;
int b;
} s;
</code></pre>
<p>假设结构体<code>s</code>的其实地址为<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>X</mi><mi>S</mi></msub></mrow><annotation encoding="application/x-tex">X_S</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.05764em;">S</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>如果让画出内存布局,我相信第一反应(包括很多网上的文章)都是像下面那样:</p>
<figure data-type="image" tabindex="1"><img src="https://zyrjm.xyz/post-images/1595856599210.png" alt="" loading="lazy"></figure>
<p>但是上述布局都是默认内存的起始地址是0或者4的倍数。但是按照我们之前的推到,只是要求<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>X</mi><mi>S</mi></msub></mrow><annotation encoding="application/x-tex">X_S</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.05764em;">S</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>是第一个成员<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>的整数倍(第一个元素位<code>char</code>,K值为1),或者<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>X</mi><mi>S</mi></msub><mo>+</mo><mi>N</mi></mrow><annotation encoding="application/x-tex">X_S+N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.05764em;">S</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>是第n个成员<code>xn</code>的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的整数倍即可,没有要求<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>X</mi><mi>S</mi></msub></mrow><annotation encoding="application/x-tex">X_S</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.05764em;">S</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>是<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">K_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>的整数倍,如果起始地址是3呢?那么内存布局是怎么样了,按照前面的规则,<code>&s.b</code>的地址刚好是4,所以不用补齐,此时结构体的大小是5,但是还必须是成员的最大<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值(对于struct St为4)的整数倍,所以结构体大小必须为8, 也就是需要早尾部填充3个字节,按照这个推出内存布局如下:</p>
</li>
</ol>
<figure data-type="image" tabindex="2"><img src="https://zyrjm.xyz/post-images/1595856612682.png" alt="" loading="lazy"></figure>
<p>这种布局一样满足所有的规则。但是经过实际的测试发现<strong>编译器位结构体首地址分配的是结构体最大<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值的整数倍</strong>(比结构体<code>struct St</code>的首地址就是4的倍数),也就是实际上确实第一种内存布局方式(但是暂时还不清楚原因是什么,也没有google到)。</p>
<p>当起始地址为1的时候也是同理,就不推导了:</p>
<figure data-type="image" tabindex="3"><img src="https://zyrjm.xyz/post-images/1595856625719.png" alt="" loading="lazy"></figure>
<p>当起始地址为2的时候:</p>
<figure data-type="image" tabindex="4"><img src="https://zyrjm.xyz/post-images/1595856633050.png" alt="" loading="lazy"></figure>
<p>可以看到如果任由起始地址任意的话,可以看到有4种可能,如果把<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>i</mi><mi>n</mi><mi>t</mi></mrow><annotation encoding="application/x-tex">int</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathdefault">i</span><span class="mord mathdefault">n</span><span class="mord mathdefault">t</span></span></span></span>替换成<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>l</mi><mi>o</mi><mi>n</mi><mi>g</mi></mrow><annotation encoding="application/x-tex">long</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord mathdefault">o</span><span class="mord mathdefault">n</span><span class="mord mathdefault" style="margin-right:0.03588em;">g</span></span></span></span>就会有8种情况,所以可能是为了统一,才规定首地址必须是最大成员<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值的倍数把。</p>
<ol>
<li>
<p>对于结构体嵌套来说,内部结构体的成员是由他自己的保证对齐的,父结构体唯一需要保证的就是结构体的起始地址是子结构体里最大<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值的整数倍,这样它内部的成员也肯定是对齐的。也可以理解为结构体的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值,就是其内部最大成员的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值</p>
</li>
<li>
<p>对于结构体元素是数组来说。起始数组也可以看做一个所有成员类型都相同的结构体,其<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值就是成员类型的K值。所以只要保证数组首地址是其<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值整数倍就行</p>
</li>
<li>
<p>还有最后一条规则,系统可以通过指令</p>
<pre><code class="language-c">#pragma pack(N)
</code></pre>
<p>指定系统对齐的字节(最大<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值)位<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>, 如果指定了,那么一个元素的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值就变成了:</p>
<p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi><mo>=</mo><mi>m</mi><mi>i</mi><mi>n</mi><mo>(</mo><mi>K</mi><mo separator="true">,</mo><mi>N</mi><mo>)</mo><mo>=</mo><mrow><mo fence="true">{</mo><mtable><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>K</mi><mo separator="true">,</mo><mspace width="1em"/><mi>K</mi><mo>≤</mo><mi>N</mi></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>N</mi><mo separator="true">,</mo><mspace width="1em"/><mi>K</mi><mo>></mo><mi>N</mi></mrow></mstyle></mtd></mtr></mtable></mrow></mrow><annotation encoding="application/x-tex"> K=min(K, N)=\left\{
\begin{aligned}
K, \quad K \le N \\
N, \quad K \gt N \\
\end{aligned}
\right. </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathdefault">m</span><span class="mord mathdefault">i</span><span class="mord mathdefault">n</span><span class="mopen">(</span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.00003em;vertical-align:-1.25003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size4">{</span></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mspace" style="margin-right:1em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p>
<p>此外在X86-64位系统下,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>的默认值位8。在32位系统下默认值为4。比如有如下结构体</p>
<pre><code class="language-c">struct S {
char a;
long b;
int c;
}
</code></pre>
<p>如果没有指定系统对齐字节数,那么<code>sizeof(S) = 24</code></p>
<p>如果指定了<code>#pragma pack(4)</code>系统对齐字节数位4,那么<code>sizeof(S) = 16</code></p>
</li>
<li>
<p>结构体对齐总结,假设结构体成员的最大K值位<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>K</mi><mrow><mi>m</mi><mi>a</mi><mi>x</mi></mrow></msub></mrow><annotation encoding="application/x-tex">K_{max}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight">x</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>, 系统指定的对齐值<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>:</p>
<ul>
<li>成员的地址必须是<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mo>(</mo><mi>N</mi><mo separator="true">,</mo><mi>K</mi><mo>)</mo></mrow><annotation encoding="application/x-tex">min(N, K)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathdefault">m</span><span class="mord mathdefault">i</span><span class="mord mathdefault">n</span><span class="mopen">(</span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="mclose">)</span></span></span></span>值的整数倍(核心规则,也是对齐的目的)</li>
<li>结构体首地址必须<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mo>(</mo><mi>N</mi><mo separator="true">,</mo><mi>K</mi><mi>m</mi><mi>a</mi><mi>x</mi><mo>)</mo></mrow><annotation encoding="application/x-tex">min(N, Kmax)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathdefault">m</span><span class="mord mathdefault">i</span><span class="mord mathdefault">n</span><span class="mopen">(</span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span><span class="mord mathdefault">m</span><span class="mord mathdefault">a</span><span class="mord mathdefault">x</span><span class="mclose">)</span></span></span></span>的整数倍</li>
<li>结构体的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值就是其最大成员的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值(用于结构体嵌套)</li>
<li>数组的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值就是其成员类型的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>K</mi></mrow><annotation encoding="application/x-tex">K</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.07153em;">K</span></span></span></span>值(用于结构体成员是数组)</li>
<li>计算结构体的大小时,可以把首地址都指定为0(因为0是任意K值的整数倍),这样便于计算。</li>
</ul>
</li>
<li>
<p>例子实战</p>
<pre><code class="language-c">struct p1 {
int i; // 4个字节
char c; // 1个字节
// Kj=4,需要保证j的首地址是Kj的倍数,需要补3个字节
int j; // 4个字节
char d; // 1个字节
// Kmax=4, 为了保证结构体大小是Kmax的倍数,需要补3个字节
}; // 4+1+3+4+1+3=12字节
struct p2 {
short i; // 2个字节
// Kj=8, 需要保证j首地址是Kj的倍数,需要补6个字节
long j; // 8个字节
char c; // 1个字节
// Kmax=8, 为了保证结构体大小是Kmax的倍数,需要补7个字节
}; // 2+6+8+1+7=24字节
struct p3 {
short w[3]; // 6个字节
char c[3]; // 3个字节
// kmax=2, 为了保证结构体大小是2的倍数,需要补1个字节
}; // 6+3+1=10字节
struct p4 {
struct p3 a[2]; // 20个字节,K=2
// 下一个成员K=8,其首地址必须是K的倍数,所以需要补4个字节
struct p2 t; // 自身24个字节, K=8
// Kmax=8, 为了保证结构体大小是Kamx的倍数,需要补4个字节
}; // 20+4+24=48字节
struct p5 {
short a; // 2个字节
// Kb=8, 补齐6字节
long b; // 8个字节
int c; // 4个字节
// Kmax=8, 补齐4字节
}; // 2+6+8+4+4=24个字节
#pragma pack(4) // 从这儿开始设置系统对齐位4字节
struct p6 { // 为了方便对比,和p5定义一样
short a; // 2个字节, K=2
// Kb=4, 只需补齐2字节
long b; // 8个字节, K=min(8, 4)=4
int c; // 4个字节
// Kmax=4 不用补齐
} // 2+2+8+4=16字节
</code></pre>
</li>
</ol>
]]></content>
</entry>
</feed>