理解指针的问题

时间:2013-07-10 22:46:16

标签: c++ pointers

以下代码来自接触的编程访谈一书 我有理解指针的概念。为什么我们不能使用代码号。 1。

代码编号。 1

bool insertInFront( IntElement *head, int data )
{
    IntElement *newElem = new IntElement;
    if( !newElem ) return false;
    newElem->data = data;
    head = newElem; // Incorrect!
    return true;
}

代码编号。 2

bool insertInFront( IntElement **head, int data )
{
    IntElement *newElem = new IntElement;
    if( !newElem ) return false;
    newElen->data = data;
    *head = newElem; // Correctly updates head
    return true;
}

4 个答案:

答案 0 :(得分:4)

  • 在代码1中,您将newElem的指针位置分配给head本地副本。当函数返回时,head被破坏,你将有一个内存泄漏(你失去指向newElem的指针,让你无法delete它。)你只有更改了指针的函数本地副本,调用者的副本不受影响。

  • 在代码2中,head是一个指向指针的指针。你没有一个指针,你实际上有一个指针指向调用者的指针。这允许你改变调用者的指针,将指针存储到newElem当函数返回时,head被销毁,但它只是指向指针的指针。原始指针在调用者的范围内是完整的。

答案 1 :(得分:1)

指针的概念非常复杂。基本上你需要考虑指针的方式是它们本身就是“价值”。这样:

*head = some_memory_address_that_points_to_head;

可以被认为是:

int im_a_pointer_to_head = some_memory_address_value_to_head;

因此,如果我们将同样的概念应用于您的第一个功能:

bool insertInFront(int im_a_pointer_to_head, int data)...

您实际上是在传递头指针值的副本,在函数中更改它只会更改为此函数创建的临时副本,并且实际上不会更改原始指针所指向的位置。

第二个函数解决了这个问题,因为你实际上是在传递指向指向头部的指针的指针副本(试着说快3倍!)。在这种情况下,您不会更改复制的值,而是更改实际指针指向的位置。

答案 2 :(得分:1)

假设你将函数1称为:

insertInFront(H, data);

在调用函数时,计算机会复制参数,然后在函数返回时释放它们。因此,在代码No.1中,head=newElemnewElem的地址分配给head(这是H的副本),然后发布headnewElem的地址永远丢失。 但是,在代码2中,该函数应该被称为:

insertInFront(&H, data);

这意味着H的地址重复headnewElem的地址分配给*head,即head指向的地方,这导致H。这样,在函数返回后,您将获得newElem的地址。

答案 3 :(得分:0)

要在函数调用之外更改通过函数参数传递的任何值(并保持更改),您必须具有要更改其值的内存地址。这是另一种说法,你必须通过引用传递"而不是"传递价值" - 否则按值传递将导致该功能仅改变COPY。