下面是我编写的用于检查内存消息的示例程序。
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吗?
答案 0 :(得分:0)
str1中的0x00616161根本不是地址,它只是该字符串的内容,即“aaa”。请注意,'a'的ascii值为0x61。所以你的陈述是17字节对齐只是对数据的错误解释。
使用malloc分配的字符串有一些额外的空间,因为每个分配因为malloc需要一些空间用于自己的内务处理,即元数据。
最后,你的堆栈变量只是简单的未初始化,所以你正在看垃圾。
答案 1 :(得分:0)
GCC使用16字节的默认堆栈对齐(参见-mpreferred-stack-boundary
选项)这就是你的指针变量(在堆栈上)与16字节对齐的原因。
变量st
是一个结构,将根据编译器认为最有效的方式打包,但通常字节将打包而不填充。您已在结构中放置了4个4字节的数组,因此不需要填充。因此,每个条目都是4字节&#39;对齐&#39;请注意,st
本身仍然以16字节边界开始,即使其元素不是。
(如果你的结构中混合了各种类型,编译器将填充它们以确保字对齐,尽管如果你有充分的理由可以使用属性来关闭填充 - 例如定义某种通信堆栈)
在堆上分配内存的方式(即malloc
)是系统的堆分配策略(c库和OS)的函数 - 它可以使用不同的分配策略,但这是一个很大的主题(参见:https://en.wikipedia.org/wiki/Heap_(data_structure))