【问题标题】:Why are pointers not located on a stack?为什么指针不在堆栈上?
【发布时间】:2009-10-27 06:59:51
【问题描述】:
void main(){
    int i,k;
    char* p;
    int j;
    printf("address of i is %d \naddress of k is %d \naddress of p is %p\naddress of j is %d", &i,&k,&p,&j);

}

当我尝试上面的代码时,j的地址是k下4个单位。但是 p 的地址并不近。既然指针是一个整型变量,可以存储 4 个字节的数据,为什么不像其他三个变量一样在栈上分配呢?

【问题讨论】:

  • 一些正式的注意事项: - main() 应该返回 int - 使用 printf() 时,始终确保将 '\n' 放在末尾。

标签: c pointers


【解决方案1】:

使用%p 打印所有地址。

剧透:它堆栈中。

【讨论】:

  • 请注意,您必须将 %p 的每个参数转换为 (void *)。到目前为止,所有代码示例都调用 undefined behavior,因为格式说明符与参数类型不匹配。虽然可能没有太大区别,但防弹代码使用#include <stdio.h>int main (void)printf ("%p\n", (void *)&p); 等。
【解决方案2】:

你应该发布你得到的输出。我怀疑您有点困惑,因为您打印的大多数地址都以十进制显示(使用 %d),而 p 以十六进制显示(使用 %p)。

【讨论】:

    【解决方案3】:

    我刚刚在我的计算机(运行 Ubuntu 9.04)上尝试了您的代码并得到以下结果:

    address of i is 0xbf96fe30
    address of k is 0xbf96fe2c
    address of p is 0xbf96fe28
    address of j is 0xbf96fe24
    

    稍微修改代码后:

    void main(){
        int i,k;
        char* p;
        int j;
        printf("address of i is %p \naddress of k is %p \naddress of p is %p\naddress of j is %p\n", &i,&k,&p,&j);
    
    }
    

    既然你所有的 printf() 都是地址,你应该使用 %p 而不是 %d。也许你误解了你的结果?

    【讨论】:

      【解决方案4】:

      当您使用 %d printf() 说明符时,您会得到一个打印为十进制数字的地址,而当您使用 %p 说明符时,您会将其打印为十六进制数字。恰好十六进制数字不包含字母,而您误解了它。

      【讨论】:

        【解决方案5】:

        到底指针是变量。就linux架构而言,很明显

        所有那些内存被本地化为函数的变量都将保留在堆栈中。

        对于上述情况,指针不应该在堆栈上是没有理由的。这是一种误解输出并忽略来自 gcc 的警告的情况。初学者会认为他们忽略 gcc 警告是无害的.有些情况相当于编译器错误

        【讨论】:

          【解决方案6】:

          我不得不告诉你,你的程序是“应该缩进六英尺并被泥土覆盖”的程序之一。 (谷歌谁说的时间和原因:-) 这是一个马虎的典型例子,原因如下,其中大部分会导致未定义的行为:

          • 使用 printf 而不包含 stdio.h
          • 使用 void main
          • 使用 %d 作为地址
          • 将 %p 与 ptr-to-void 以外的东西一起使用

          正确的写法是这样的:

          #include <stdio.h>
          
          int main (void)
          {
              int i, k;
              char *p;
              int j;
          
              printf ("address of i is %p\n", (void *)&i);
              printf ("address of k is %p\n", (void *)&k);
              printf ("address of p is %p\n", (void *)&p);
              printf ("address of j is %p\n", (void *)&j);
              return 0;
          }
          

          【讨论】:

            【解决方案7】:

            指针可能位于也可能不在堆栈上,因为它们也是某种变量。请注意,它们是一些不是很大的变量。如果 CPU/MCU 有很多寄存器并且编译器优化得很好,你可能在堆栈上看不到指针,它很可能在寄存器中度过了整个生命周期。

            【讨论】:

            • 在 OPs 的情况下,编译器无法优化指针变量,因为代码期望获取变量 (&p) 的内存地址,这对寄存器无效。
            • @Frank:我指的是问题(标题本身),而不是给定的代码 sn-p...
            • 详细阐述问题是否有罪:-)
            • @Malkocoglu:不,不是,但是您应该以某种方式明确表示您的答案并未引用 OP 的实际问题。您还应该考虑,在寻找解决问题的方法时,您的回答可能会导致 OP 进入错误的方向。
            猜你喜欢
            • 2013-04-11
            • 2019-08-27
            • 2019-11-23
            • 2012-02-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-19
            • 2013-01-20
            相关资源
            最近更新 更多