簡體   English   中英

堆棧、堆中的內存是如何排列的?

[英]How is memory arranged in stack, heap?

下面是我編寫的用於檢查內存對齊的示例程序。

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 在堆中使用內存!?

str1 中的 0x00616161 根本不是地址,它只是該字符串的內容,即“aaa”。 請注意,'a' 的 ascii 值為 0x61。 因此,您關於這是 17 字節對齊的聲明只是對數據的錯誤解釋。

使用 malloc 分配的字符串有一些額外的空間,因為對於每個分配,因為 malloc 需要一些空間來處理它自己的內務,即元數據。

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

GCC 使用 16 字節的默認堆棧對齊(請參閱-mpreferred-stack-boundary選項)這就是為什么您的指針變量(位於堆棧上)對齊為 16 字節的原因。

變量st是一個結構體,將根據編譯器認為最有效的方式進行打包,但通常字節會在不進行填充的情況下進行打包。 您在結構中放置了 4 個 4 個字節的數組,因此不需要填充。 因此,每個條目都是 4 字節的“對齊”。 請注意, st本身仍然以 16 字節邊界開始,即使它的元素不是。

(如果您的結構中有多種類型,編譯器將填充它們以確保字對齊,盡管如果有充分的理由,您可以使用屬性來關閉填充 - 例如定義某種通信堆棧)

在堆上分配內存的方式(即通過malloc )是系統(c 庫和操作系統)的堆分配策略的函數 - 可以使用不同的分配策略,但這是一個很大的話題(請參閱: https ://en.wikipedia.org/wiki/Heap_(data_structure) )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM