C打印指向数组的指针地址问题

C打印指向数组的指针地址问题,c,pointers,memory,memory-address,C,Pointers,Memory,Memory Address,当我运行以下代码时: #include <stdio.h> #include <stdlib.h> int main(void) { int array[100]; int (*array_ptr)[100]; void *buff = malloc(500); int *ptr; printf("array: %p \narray+1: %p\n", array, array+1); printf("array_ptr:

当我运行以下代码时:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int array[100];
    int (*array_ptr)[100];
    void *buff = malloc(500);
    int *ptr;
    printf("array: %p \narray+1: %p\n", array, array+1);
    printf("array_ptr: %p \narray_ptr+1: %p\n", array_ptr, array_ptr+1);
    printf("buff: %p\n", buff);
    printf("ptr: %p\n", ptr);
}
我多次运行它,
array
array+1
buff
ptr
都会随机更改值,但
array\u ptr
array\u prt+1
从未更改,尽管指针算术结果
0x190
与预期一致

它是否指示
array_ptr
指向的数组存储在heap中?但是
buff
指向的动态分配内存块也应该在堆中,并且它的值会发生变化,这是为什么?谢谢

它是否指示
array_ptr
指向的数组存储在heap中

否。
array\u ptr
在堆栈或堆上都不指向任何内容


array_ptr
是一个指向100个
int
对象数组的指针,但使用此语句,您不会创建一个包含100个
int
对象的数组,通过该对象
array_ptr
指向此数组的第一个元素。它只创建指针本身

与:

您正试图打印指针
array_ptr
及其偏移量为1点的对象地址,但这是不可能的,因为
array_ptr
未初始化为指向此类对象。因此,你会得到任何类型/不可预测的结果

您需要使用
数组
的第一个
int
对象的地址初始化
数组

int (*array_ptr)[100] = array;
指针
ptr
的情况也一样:

printf("ptr: %p\n", ptr);
ptr
需要有它指向的对象的地址才能显示该对象的地址

但是
buff
指向的动态分配内存块也应该在堆中,并且它的值会发生变化,这是为什么


这是完全不同的事情。使用
malloc
可以在堆上分配内存(当然,如果成功的话),并且可以获得指向该内存的指针,而
int(*array_ptr)[100]则不是这样

数组_ptr
是未初始化的指针,并获取未定义的值(在您的示例中为0)

array_ptr+1
比array_ptr大100=400=0x190

ptr
也是一个uninit指针,在您的例子中,它指向垃圾

您需要在定义指针之后初始化指针以获得任何有效结果


对于您的问题,
array
在堆栈上,
buff
在堆上,
ptr
/
array\u ptr
未初始化会给您带来垃圾或分段错误,如果您试图访问它们的数据

您的指针
array\u ptr
未初始化,它不会指向任何地方,它的值将是不确定的。与
ptr
相同。在C语言中也是如此。谢谢@Someprogrammerdude,但是为什么
array\u ptr+1
的值仍然可用?最后,堆中存储的唯一内容是使用
malloc
分配的500字节。但是请注意,变量
buff
本身的存储不在堆上,它只指向堆。这无法编译。为了使用
malloc
,您需要
#包含
。在这种情况下,未定义的行为似乎是未初始化的变量
array_ptr
的值为0(无论该值是变量所在堆栈上的附带值还是我们不知道它是否为调试模式初始化);因此,增加它将指向“下一个数组”,即400 resp。其后面的0x190字节(100整数数组占用的内存)。0+400=400,这是打印的地址。
printf("array_ptr: %p \narray_ptr+1: %p\n", array_ptr, array_ptr+1);
int (*array_ptr)[100] = array;
printf("ptr: %p\n", ptr);