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