现在已经困扰我一个多星期了。我可能错过了解释这一问题的帖子,但是我读了很多帖子/文章,它们要么不告诉我任何我不知道的内容,要么不知所措。

考虑一下:

#include<iostream>
using namespace std;

void poo(int *currArray){
    cout << "*currArray: " << currArray << endl;
    int * blah = new int [5];
    cout << "blah: " << blah << endl;

    currArray = blah;
    cout << "currArray after switch " << currArray << endl;
}

int main(){
    int * foo = new int [5];

    cout << "foo: " << foo << endl;

    poo(foo);

    cout << "foo after poo " << foo << endl;
}


产生输出:

foo: 0x7ffdd5818f20
*currArray: 0x7ffdd5818f20
blah: 0x7ffdd5818ef0
currArray after switch 0x7ffdd5818ef0
foo after poo 0x7ffdd5818f20


如您所见,虽然地址切换发生在函数内部,但它不会延续到主函数中。我也知道这正在泄漏内存,但是我认为这与问题无关。

我的理解是,数组本质上指向其第一个元素的地址。据我了解,数组是通过“引用”传递的。即,传递数组的地址。

那么为什么poo之后地址切换不持续呢?我是否没有将作为currArray别名的foo指针更改为blah指针?

最佳答案

什么是指针?它是一个包含内存地址的变量。它可以被复制,可以被引用,甚至可以使用它的地址。因此,当您将函数声明为void poo(int *currArray)时,就是说,将传递的参数的值复制到变量currArray中。因此,currArray现在包含与foo相同的地址。但是,更改currArray的值时,只能更改currArray的值,因为它是副本,而不是引用。

您可以看到卡尔关于如何通过引用传递指针的答案。可以修改foo的另一种方法是将foo的地址传递给该函数。由于现在您知道foo在内存中的位置,因此可以通过取消引用并为其分配blah地址来更改其值。当然,您应该首先释放foo占用的内存(通过currArray),因为如果您不这样做,则以后将无法执行此操作,并且会导致内存泄漏。

这是示例代码:

#include<iostream>

void poo(int **currArray)
{
    std::cout << "currArray: " << *currArray << std::endl;
    int *blah = new int[5];
    std::cout << "blah: " << blah << std::endl;
    delete[] *currArray; // clean after ourselves
    *currArray = blah;
    std::cout << "currArray after switch " << *currArray << std::endl;
}

int main()
{
    int *foo = new int[5];
    std::cout << "foo: " << foo << std::endl;
    poo(&foo);
    std::cout << "foo after poo " << foo << std::endl;
    delete[] foo; // clean after ourselves
}


演示:https://ideone.com/4UWYlG

foo: 0x560b3e9ffc20
currArray: 0x560b3e9ffc20
blah: 0x560b3ea00c50
currArray after switch 0x560b3ea00c50
foo after poo 0x560b3ea00c50

10-04 14:48