使用指针通过引用传递数组的混淆

时间:2016-11-28 22:36:50

标签: c++ arrays pointers reference

几个小时前我刚问了一个问题,我对答案中指出的问题感到困惑(arrays using pointers in c++: segmentation fault when accessing the returned array)。有些人对我的新问题反应有点负面,所以我查阅了关于指针的书,这对我没什么帮助。所以,我再来一次。

在上一个问题中,我有一个函数void builder(int aSize1, int aSize2, int aSize3, int*** frequencies),我认为它会为传递给int*** frequencies参数的3d数组动态分配内存并初始化它。但是,我被告知只有一个副本会被传递到该函数中,我将分配和初始化只是为了副本而不是原始。因此,他们建议我使用引用,将函数原型呈现为void builder(int aSize1, int aSize2, int aSize3, int***& frequencies)

然而,我回想起昨天,当我第一次偶然发现使用指针传递引用的概念时,人们也可以操纵指针的数据。好的,

void change_what_this_points_to( int* a )
{
    *a = 42;
}

此函数确实会更改输入函数的指针的值。

所以,我的问题是,为什么前者传递副本而后者传递真实交易?除了一个有更多星号的事实之外,我认为这两个函数之间并没有太大区别。

任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:2)

虽然另一个答案说得很完美但我只是想加上我的两美分以防它有所帮助。将指针视为内存中的地址。您将该地址传递给函数,函数在那里写入一些东西。然后在调用函数之后,您可以查看内存中的相同位置并查看其中的值。

因此,我们假设您有以下代码:

void SetValue(int *a){ *a = 10;}
void DoWork()
{
    int a; 
    SetValue(&a); 
}

SetValue函数将一个指向int的指针作为参数,或者我们将其视为一个存储int的内存中的地址。然后,该函数只将数字10写入传入的地址。

DoWork方法然后为int创建内存并将该内存的地址传递给该函数。因此,当DoWork返回存储“a”的内存时,其值为10.听起来你已经从你的问题中得到了这个,但是为了以防万一,我想从这里开始。

现在让我们假装您想要一个为您分配内存的功能。你真正要求函数做的是分配内存并告诉我内存在哪里。所以你可以用指针返回值来做,即

int* AllocateMemoryForMe()
{
    return new int(); //Creates memory for an int, let's pretend it's at location 0x100
}
void DoWork()
{
    int* a = NULL; // a has a value of 0x00
    a = AllocateMemoryForMe(); //a will now have the value of 0x100
    *a = 10; //We now write 10 to memory location 0x100
}

或者您可以使用指针执行此操作。如果你这样做,你实际要做的是将函数传递给内存中的一个位置,以便将分配的内存的地址写入,所以指向指针的指针。因此,当函数返回时,您可以查看此地址并查看新创建的内存的地址。例如:

void AllocateMemoryForMe(int** x)
{
    *x = new int(); //allocates memory for an int, let's pretend it's at memory location 0x200
}
void DoWork()
{
    int** a = new int*(); //Creates memory for an int pointer. Let's pretend it allocates memory at location 0x100. 
    AllocateMemoryForMe(a); //pass memory location 0x100 to the function.
    //Right now the address of a is still 0x100 but the data at the memory location is 0x200. This is the address of the int we want to write to.
    **a = 10; //This will now write 10 to the memory location allocated by the AllocateMemoryForMe() function. 

}

答案 1 :(得分:1)

< p>此函数< / p> < pre>< code> void change_what_this_points_to(int * a) {     * a = 42; } < /代码>< /预> < p>不会改变指针本身。它会更改指针指向的整数对象。< / p> < p>如果要更改指针本身,则应按以下方式编写函数< / p> < pre>< code> void change_what_this_points_to(int *& a) {     a = new int(42); } < /代码>< /预> < p>或以下方式< / p> < pre>< code> void change_what_this_points_to(int ** a) {     * a = new int(42); } < /代码>< /预> < p>因此返回到您的函数时,您应该将其声明为< / p> < pre>< code> void builder(int aSize1,int aSize2,int aSize3,int ***& frequency); < /代码>< /预> < p>或类似< / p> < pre>< code> void builder(int aSize1,int aSize2,int aSize3,int **** frequency); < /代码>< /预>