C 带安培和vs pmap的可变内存位置

C 带安培和vs pmap的可变内存位置,c,memory,C,Memory,我刚开始在C中处理指针,有一件事让我困惑 下面是简单的代码: int main () { long ms = 10000000; int var1; char var2[10]; printf("Address of var1 variable: %x\n", &var1 ); printf("Address of var2 variable: %x\n", &var2 ); printf("Sizeof of var2 varia

我刚开始在C中处理指针,有一件事让我困惑

下面是简单的代码:

int main ()
{

   long ms = 10000000;

   int  var1;
   char var2[10];

   printf("Address of var1 variable: %x\n", &var1  );
   printf("Address of var2 variable: %x\n", &var2  );
   printf("Sizeof of var2 variable: %d\n", sizeof(var2) );

   retpid();
   millisleep(ms);

   return 0;
}
和-返回var1和var2内存地址(我相信是虚拟内存):

但是-当我运行
pmap
-我在那里看不到以下地址:

$ pmap -x 15885
15885:   ./address
Address           Kbytes     RSS   Dirty Mode   Mapping
0000000000400000       4       4       0 r-x--  address
0000000000600000       4       4       4 rw---  address
00007fcdb6bbc000    1576     256       0 r-x--  libc-2.12.so
00007fcdb6d46000    2048       0       0 -----  libc-2.12.so
00007fcdb6f46000      16      16      16 r----  libc-2.12.so
00007fcdb6f4a000       4       4       4 rw---  libc-2.12.so
00007fcdb6f4b000      20      12      12 rw---    [ anon ]
00007fcdb6f50000     128     104       0 r-x--  ld-2.12.so
00007fcdb7160000      12      12      12 rw---    [ anon ]
00007fcdb716d000       8       8       8 rw---    [ anon ]
00007fcdb716f000       4       4       4 r----  ld-2.12.so
00007fcdb7170000       4       4       4 rw---  ld-2.12.so
00007fcdb7171000       4       4       4 rw---    [ anon ]
00007fff79780000      84      12      12 rw---    [ stack ]
00007fff797ff000       4       4       0 r-x--    [ anon ]
ffffffffff600000       4       0       0 r-x--    [ anon ]
----------------  ------  ------  ------
total kB            3924     448      80

我在这里错过了什么?

也许您只是错过了指针值的一半。打印指针的正确格式是
%p
,在具有64位地址和32位
int
的机器上,这会产生“显著”的差异。

我认为您缺少两件事:

  • 内存地址空间似乎是64位的,因此应该使用
    %p
    而不是
    %x

  • 正在打印的变量是局部变量,因此位于堆栈中的某个位置

  • 打印完整的8字节地址后,您将看到它们都位于堆栈中

    换句话说,在从地址0x00007fff79780000开始的84 KB内存段内


    顺便说一句,当传递指向
    printf
    的指针时,在任何情况下通常都应该使用
    %p


    恰好在32位系统上,使用
    %x
    会产生与
    %p
    相同的结果,在64位指针上使用32位
    %x
    ,也就是
    7fff
    ,在输出前面加上前缀:
    7ff79780000

    使用
    %p
    打印指针,方法是将指针强制转换为
    void*

    printf("Address of var1 variable: %p\n", (void*) &var1);
    

    还请注意,
    var2
    已经是一个指针<代码>&var2仍然有效,因为它似乎

    这三个都是一样的,但最后一个对我来说不是很合乎逻辑:

    • var2
    • &var2[0]
    • &var2

    嗯。。。如果我设置
    intvar1=10;char var2[10]=“内存”在顶部(这使它们成为全局的,对吗?)-结果我有了类似0x600ab4:-|和yes的地址-我将
    %x
    更改为
    %p
    。另外,如果我将它们设置回
    main(),并使用
    %p`-我有像
    0x7fff0caba0c4
    -这样的“正常”地址,但仍然无法在
    pmap
    结果中找到它…@setevoy:回答您的问题:1。为了全球化,它们必须在任何功能之外,而不一定是“在顶端”。它们必须仅位于使用它们的位置的“顶部”,但这只是为了让程序能够编译(而不是让它们成为全局的)。2.
    0x7fff0caba0c4
    不是您在问题中指定的地址之一。那么它指的是什么呢?
    var1变量的地址:0x7fffe5765f94 var2变量的地址:0x7fffe5765f80
    #cat/proc/16334/maps
    给出了7
    fffe5752000-7fffe5767000 rw-p 00000000:00[stack]
    -所以你是对的,它在stack@barak manos里面我一遍又一遍地重写脚本,试图找到解决方案,因此每次都重新启动它,现在地址将被删除different@setevoy:它被称为数据部分,是所有
    非静态全局
    静态全局
    静态局部
    变量所在的位置。在整个程序执行过程中,这些变量的地址是恒定的。与这三种“类型”不同,任何
    非静态局部
    变量都位于堆栈中,其地址在程序执行期间可能会发生变化,这取决于调用函数(声明变量)时堆栈的状态。是的,真的:`printf(“var2变量的地址:%p\n”,&var2);printf(“var2[0]变量的地址:%p\n”,&var2[0]);`结果
    var2变量的地址:0x7fff9ad943c0 var2[0]变量的地址:0x7fff9ad943c0
    “…
    var2
    已经是指针。”:不,
    var2
    不是指针,它是数组。将其传递给函数(
    printf()
    此处)会使数组衰减为指针(指向其第一个元素);是相当不确定的,因为var2是一个数组,任何对数组名称的引用都会得到数组的地址,所以不需要“&”这些变量在堆栈上,堆栈的地址是:00007fff79780000,这些变量不是全局可见的,所以您不会看到它们列出。
    printf("Address of var1 variable: %p\n", (void*) &var1);