C 内存是如何安排在堆栈、堆中的?

C 内存是如何安排在堆栈、堆中的?,c,malloc,padding,heap-memory,stack-memory,C,Malloc,Padding,Heap Memory,Stack Memory,下面是我编写的用于检查内存关联的示例程序 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

下面是我编写的用于检查内存关联的示例程序

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;
    }
Pavan@Pavan-pc:~/working\u dir/pavan/C$cat mem3.C
#包括
#包括
#包括
/*这是由模板程序生成的*/
类型定义结构结构{
字符str1[4],str2[4],str3[4];
}结构;
int main(){
stru_t st;
字符str1[4],str2[4],str3[4];
字符*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”);
返回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
Pavan@Pavan-pc:~/working\u dir/pavan/C$gdb mem3
GNU gdb(gdb)Red Hat Enterprise Linux(7.2-60.el6_4.1)
版权所有(C)2010免费软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本
这是自由软件:您可以自由更改和重新发布它。
在法律允许的范围内,不存在任何担保。键入“显示复制”
和“显示保修”了解详细信息。
此GDB配置为“x86_64-redhat-linux-gnu”。
有关错误报告说明,请参阅:
...
从/home/xkumapu/working_dir/pavan/C/mem3读取符号…完成。
(gdb)b 1
0x4005f0处的断点1:文件mem3.c,第1行。
(gdb)r
启动程序:/home/xkumapu/working_dir/pavan/C/mem3
[已启用使用libthread_db的线程调试]
断点1,main()位于mem3.c:17
17 mstr1=(char*)malloc(4);
缺少单独的调试信息,请使用:debuginfo安装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返回0;
(gdb)
31      }
(gdb)x str1
0x7FFFFFE330:0x00616161
(gdb)x str2
0x7FFFFFE320:0x00626262
(gdb)x str3
0x7FFFFFE310:0x00636363
(gdb)x&str3
0x7FFFFFE310:0x00636363
(gdb)x&str2
0x7FFFFFE320:0x00626262
(gdb)x和str1

0x7FFFFFE330:0x00616161str1中的0x00616161根本不是地址,它只是该字符串的内容,即“aaa”。请注意,“a”的ascii值为0x61。因此,您声明这是17字节对齐的,这只是对数据的错误解释

使用malloc分配的字符串有一些额外的空间,因为对于每个分配,malloc需要一些空间用于自己的内部管理,即元数据


最后,您的堆栈变量只是未初始化,因此您正在查看垃圾。

GCC使用16字节的默认堆栈对齐方式(请参阅
-mprefered stack boundary
选项),这就是指针变量(位于堆栈上)对齐16字节的原因

变量
st
是一种结构,它将根据编译器认为最有效的方式进行打包,但通常字节将打包而不填充。您已经在结构中放置了4个4字节的数组,因此不需要填充。因此,每个条目都是4字节“对齐”的。请注意,
st
本身仍然以16字节边界开始,即使其元素不是这样

(如果您的结构中混合了多种类型,编译器将填充它们以确保单词对齐,但如果您有充分的理由(例如,定义某种类型的comms堆栈),可以使用属性关闭填充)


在堆上分配内存的方式(即通过
malloc
)是系统(c库和操作系统)堆分配策略的一个功能-可以使用不同的分配策略,但这是一个大主题(请参阅:)

Rob,感谢您对我的帮助。另外,谢谢你指出16分17的错误。(我改了)。我的主要问题是,为什么堆栈中需要16字节-->这是一个主要问题。结构中有4个字节->应为。40字节->可能是由于内存控制块。需要解释。希望你能帮我解决这些问题看起来是别人给了我一个很好的解释。你所做的一切都是好的:使用调试器深入了解事物,尝试理解你所看到的,然后如果需要的话问问题。你所说的“MCB”是什么意思?@kalaracey Memory control block。在每个动态分配的内存块之前追加的结构。此结构包含两个值{is_available,size}。