Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么指针不在堆栈上?_C_Pointers - Fatal编程技术网

C 为什么指针不在堆栈上?

C 为什么指针不在堆栈上?,c,pointers,C,Pointers,当我尝试上述代码时,j的地址比k低4个单位。但是p的地址不在附近。既然指针是一个可以存储4字节数据的整数变量,为什么不像其他三个变量那样在堆栈上分配它呢?使用%p打印所有地址 扰流板:它在堆栈上。你应该发布你得到的输出。我怀疑您有点困惑,因为您正在打印的大多数地址都是以十进制(使用%d)显示的,p是以十六进制(使用%p)显示的。我刚刚在我的计算机上尝试了您的代码(运行Ubuntu 9.04),得到了以下结果: void main(){ int i,k; char* p;

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

使用
%p
打印所有地址


扰流板:它在堆栈上。

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

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

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);

}
稍微更改代码后:

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

由于printf()都是地址,所以应该使用%p而不是%d。也许您误解了结果?

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

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

最后指针是一个变量。就linux体系结构而言,很明显


所有那些内存局限于某个函数的变量都将保留在堆栈上。我不得不告诉您,您的程序是“应该缩进六英尺并覆盖灰尘”的程序之一。(谷歌搜索who何时以及为什么这么说:-) 这是马虎的一个主要例子,原因如下,其中大多数是导致未定义的行为:

  • 使用printf而不包括stdio.h
  • 使用void main
  • 使用%d作为地址
  • 将%p与ptr以外的内容一起使用以作废
如果写得正确,它看起来是这样的:

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);

}
#包括
内部主(空)
{
int i,k;
char*p;
int j;
printf(“i的地址为%p\n”,(void*)&i);
printf(“k的地址为%p\n”,(void*)&k);
printf(“p的地址为%p\n”,(void*)&p);
printf(“j的地址为%p\n”,(void*)&j);
返回0;
}

一些正式说明:-main()应该返回int-当使用printf()时,一定要确保在末尾加上“\n”。在OPs的情况下,编译器无法优化指针变量,因为代码希望得到变量(&p)的内存地址,这对于寄存器来说是无效的。@Frank:我指的是这个问题(标题本身),不是给定的代码片段…详细说明问题是有罪的吗:-)@Malkocoglu:不是,但是你应该弄清楚,你的答案没有提到实际问题。您还应该考虑,当您寻找解决问题的方法时,您的答案可能会导致OP进入错误的方向。请注意,必须将%P的每个参数都转换为<代码>(无效*)< /代码>。由于格式说明符与参数类型不匹配,到目前为止所有代码示例都调用未定义的行为。防弹代码使用
#include
intmain(void)
printf(“%p\n”、(void*)&p)虽然可能没有多大区别等。
#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;
}