2016-11-28 49 views
0

几个小时前我刚刚问过一个问题,我一直对答案中指出的某些事情感到困惑(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; 
} 

这个函数改变被送入的功能的指针的值。

所以,我的问题是,为什么前者通过副本而后者通过实际交易?除了人们有更多的星号之外,我没有看到这两种功能之间有太大的区别。

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

+0

它们表示您传递*指针*的副本,而不是它指向的内容。 – juanchopanza

+0

在C++语言编程时,不要乱用原始指针。从上个世纪就是如此。请走向现代。 –

+0

@πάνταῥεῖ我在最后一个问题中有类似的评论,我会作出相应的回应。我对C++和指针的概念很陌生,并且想了解底层的东西。恕我直言,我没有看到在这方面的伤害:) – Astaboom

回答

1

此功能

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

不会改变指针本身。它改变指针指向的整数对象。

如果你想改变指针本身,你应该写函数以下任一方式

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

或通过以下方式

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

并返回到你的函数应声明它要么喜欢

void builder(int aSize1, int aSize2, int aSize3, int*** &frequencies); 

或类似

void builder(int aSize1, int aSize2, int aSize3, int**** frequencies); 
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. 

}