gpt4 book ai didi

c - 栈、堆中的内存是如何排列的?

转载 作者:行者123 更新时间:2023-11-30 19:35:57 28 4
gpt4 key购买 nike

下面是我编写的用于检查内存对齐的示例程序。

Pavan@Pavan-pc:~/working_dir/pavan/C$ cat mem3.c
#include <stdio.h>
#include <string.h>
#include <stdio.h>

/* This is generated by a template program */

typedef struct stru_s{
char str1[4], str2[4], str3[4];
}stru_t;
int main(){
stru_t st;

char str1[4], str2[4], str3[4];

char *mstr1, *mstr2, *mstr3, *mstr4, *mstr5;;

mstr1= (char*)malloc(4);
mstr2= (char*)malloc(4);
mstr3= (char*)malloc(4);
mstr4= (char*)malloc(8);
mstr5= (char*)malloc(16);

strcpy(str1, "aaa");
strcpy(str2, "bbb");
strcpy(str3, "ccc");
strcpy(mstr1, "xxx");
strcpy(mstr2, "yyy");
strcpy(mstr3, "zzz");

return 0;
}

下面是使用gdb检查内存。

Pavan@Pavan-pc:~/working_dir/pavan/C$ gdb mem3
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/xkumapu/working_dir/pavan/C/mem3...done.
(gdb) b 1
Breakpoint 1 at 0x4005f0: file mem3.c, line 1.
(gdb) r
Starting program: /home/xkumapu/working_dir/pavan/C/mem3
[Thread debugging using libthread_db enabled]

Breakpoint 1, main () at mem3.c:17
17 mstr1= (char*)malloc(4);
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.x86_64
(gdb) n
18 mstr2= (char*)malloc(4);
(gdb) n
19 mstr3= (char*)malloc(4);
(gdb) n
20 mstr4= (char*)malloc(8);
(gdb) n
21 mstr5= (char*)malloc(16);
(gdb) n
23 strcpy(str1, "aaa");
(gdb) n
24 strcpy(str2, "bbb");
(gdb)
25 strcpy(str3, "ccc");
(gdb)
26 strcpy(mstr1, "xxx");
(gdb)
27 strcpy(mstr2, "yyy");
(gdb)
28 strcpy(mstr3, "zzz");
(gdb)
30 return 0;
(gdb)
31 }
(gdb) x str1
0x7fffffffe330: 0x00616161
(gdb) x str2
0x7fffffffe320: 0x00626262
(gdb) x str3
0x7fffffffe310: 0x00636363
(gdb) x &str3
0x7fffffffe310: 0x00636363
(gdb) x &str2
0x7fffffffe320: 0x00626262
(gdb) x &str1
0x7fffffffe330: 0x00616161 <- Aligned to 16 bytes. (from 320 to 330)
(gdb) x &mstr1
0x7fffffffe358: 0x00601060
(gdb) x &mstr2
0x7fffffffe360: 0x006010a0
(gdb) x &mstr3
0x7fffffffe368: 0x006010e0 <- aligned to 40 bytes. (from 0a0 to 0e0)
(gdb) x &st.str
There is no member named str.
(gdb) x &st.str3
0x7fffffffe348: 0x00400735
(gdb) x &st.str2
0x7fffffffe344: 0x00007fff
(gdb) x &st.str1
0x7fffffffe340: 0xffffe478 <- Aligned to just 4 bytes.(from 340 to 344)
(gdb) q
A debugging session is active.

Inferior 1 [process 12541] will be killed.

Quit anyway? (y or n) y

有人可以解释一下为什么结构中需要不同类型的对齐方式吗?而且是MCB使用了堆内存吗!?

最佳答案

GCC 使用默认的 16 字节堆栈对齐(请参阅 -mpreferred-stack-boundary 选项)这就是为什么指针变量(位于堆栈上)对齐到 16 字节。

变量 st 是一个结构,将根据编译器认为最有效的方式进行打包,但通常字节会打包而无需填充。您已在结构中放入 4 个 4 字节数组,因此不需要填充。因此每个条目都是 4 字节“对齐”的。请注意,st 本身仍然从 16 字节边界开始,尽管它的元素并非如此。

(如果您的结构中有多种类型,编译器将填充它们以确保字对齐,尽管如果您有充分的理由,您可以使用属性来关闭填充 - 例如定义某种通信堆栈)

在堆上分配内存的方式(即通过malloc)是系统(C 库和操作系统)堆分配策略的函数 - 可以使用不同的分配策略但这是一个大话题(参见:https://en.wikipedia.org/wiki/Heap_(data_structure))

关于c - 栈、堆中的内存是如何排列的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41909037/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com