0

我似乎无法理解为什么我的指针在这种情况下会改变地址:

int *load(FILE *fp, int * vector, int w, int h){
    //other coding
    int array[w][h];
    int *ptr = &array;
    return ptr;
}

main(){
    //other coding
    int *ptr = load(file, vector, w, h);
    printf("%d ", *(ptr));
    printf("%d ", *(ptr));
}

在我的第一个printf("%p ", *(ptr));它打印00000010

在我的第二个printf("%p ", *(ptr));它打印0028fc6c

并且可以肯定的是,如果我打印"%d"第一个值是好的,第二个不是。

4

4 回答 4

1

array您返回的地址load()是该函数的局部变量。您永远不应该返回它的地址,因为它分配在堆栈上,并且将被重用于后续的函数调用。

您看到的更改值是因为对printf()s 的调用正在更新堆栈的该位置。

于 2013-10-08T05:54:42.023 回答
0

当您打印 *(ptr) 时,它会尝试打印位置 ptr 的值,如果要打印 ptr 的地址,请尝试 &(ptr)。

于 2013-10-08T05:57:50.007 回答
0

首先,您不是在打印指针,而是在打印指针指向的值。这就是一元运算符的*作用:它使您可以访问指向的值。因此,您观察到的任何内容都没有以任何方式暗示某些“地址”已更改。您没有检查程序中的任何地址。

其次,以上可能意味着改变的不是指针。改变的是指向值。实际上,您从函数返回的指针指的是无效的内存位置(不再存在的以前本地数组的位置)。无效的内存位置在没有任何明显原因的情况下更改其值这一事实并没有什么不寻常的。它被称为未定义的行为。您的程序可能已经崩溃,但是出于纯粹的运气而不是崩溃,您得到的值会“莫名其妙地”改变。

第三,即使您的代码可能被宽松的编译器“编译”,它仍然包含约束违规,即“编译错误”。此初始化无效

int *ptr = &array;

&array值具有类型int (*)[w][h]。它不能用于初始化类型的指针int *。我相信编译器已经告诉过你了。您必须密切注意编译器发出的诊断消息。

于 2013-10-08T06:05:19.717 回答
0

您正在尝试打印本地声明的数组的地址。在函数外部声明数组,即全局声明。

试试这个方法:

int array[w][h];


int *load(FILE *fp, int * vector, int w, int h){
    //other coding
    int *ptr = &array;
    return ptr;
}

main(){
    //other coding
    int *ptr = load(file, vector, w, h);
    printf("%d ", *(ptr));    
}
于 2013-10-08T06:15:05.560 回答