【问题标题】:Question on Call-By-Reference?关于按引用调用的问题?
【发布时间】:2010-02-15 13:50:34
【问题描述】:

main() 使用参数参数 First Node 调用 Call_By_Test() 函数。 我在 Call_By_Test() 中释放了第一个节点,但在 main() 中没有释放第一个节点地址,为什么?。

typedef struct LinkList{
int data;
struct LinkList *next;
}mynode;

void Call_By_Test(mynode * first)
{
        free(first->next);
        first->next = (mynode *)NULL;
        free(first);
        first = (mynode *)NULL;
}
int main()
{
mynode *first;

first = (mynode *)malloc(sizeof(mynode));
first->data = 10;
first->next = (mynode *)NULL;

cout<<"\n first pointer value before free"<<first<<endl;

Call_By_Test(first);
// we freed first pointer in Call_By_Test(), it should be NULL
if(first != NULL)
        cout<< " I have freed first NODE in Call-By-Test(), but  why first node pointer has the value "<<first<<endl;


}

输出: 第一个指针值 0x804b008 我在 Call-By-Test() 中释放了第一个节点,但是为什么第一个节点指针的值是 0x804b008

【问题讨论】:

  • @SIVA:如果您对过去 6 个问题的某些答案感到满意,您应该接受它们(通过单击空心复选标记)。
  • 您在 Call_By_Test 中做了两件不同的事情:您调用 free(ptr)ptr=NULL。您希望这两者中的哪一个会影响 main() 中的 first
  • 我仍然想知道为什么大多数人从 C 子集开始学习 C++...
  • 这不是 C++ 代码,这是带有 cout 而不是 printf 的 C。

标签: c++ pass-by-reference argument-passing


【解决方案1】:

答案是您没有使用传递引用。您正在按值传递指针 - 这不是一回事。这意味着您将看到指针所指数据的变化,但在 Call_By_Test 方法中更改 first 本身的值没有任何作用。

【讨论】:

    【解决方案2】:

    由于问题被标记为 c++,我将重构为:

    void Call_By_Test( mynode *& first ) // rest of code remains the same
    

    这传达了传递引用而没有额外的取消引用。建议将指针传递给指针 (void Call_By_Test( mynode ** first )) 的所有解决方案都在指向指针变量的指针中使用按值传递语义。虽然您可以在 C++ 中执行此操作,但传递引用更清晰。

    【讨论】:

    • +1。好点子。即使当您阅读代码时,它也会大喊“C”!!!。我什至没有注意到 C++ 标签:)
    【解决方案3】:

    在函数中

    void Call_By_Test(mynode * first)
    

    first 实际上是函数的局部变量。更改它不会更改程序其余部分的状态。您需要对指针的引用或指向指针的指针:

    void Call_By_Test(mynode ** first)
    {
            free((*first)->next);
            (*first)->next = NULL;
            free(*first);
            *first = NULL;
    }
    

    并称之为:

    Call_By_Test( & first );
    

    【讨论】:

      【解决方案4】:

      当你这样做时:

      void Call_By_Test(mynode * first)
      

      您先复制,因此您可以先处理位于其中的内容,但您不能先更改地址,因为它是副本。

      如果你想先改变值,那么你应该有一个这样的函数:

      void Call_By_Test(mynode ** first)
      

      void Call_By_Test(mynode & first)
      

      它允许您首先访问参数,就好像它是原始变量(而不是主函数的副本)

      【讨论】:

        【解决方案5】:

        如果您 free 一个指针(例如 0x804b008),则不会更改指针本身的位。它仅允许 C++ 库记录指向地址处的内存不再使用,并且可以回收。在您的情况下,当您打印 0x804b008 时,地址 0x804b008 的内存可供 C++ 库重用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-02
          • 1970-01-01
          • 2011-10-11
          相关资源
          最近更新 更多