【问题标题】:Access violation when using double pointer使用双指针时访问冲突
【发布时间】:2013-11-02 18:25:51
【问题描述】:

我有一个函数func(),它接受一个双指针。如果它指向零,则函数退出(第一次检查)。现在没有第二次检查,我在尝试访问 mybar 的成员时遇到访问冲突(仅当我第二次运行该函数时)。这是为什么?如果mybar == NULL 不应该在第一次检查时退出?

func( Foo **bar )
{
    //First check
    if(bar== NULL)
    return;

    Foo *mybar = *bar;

    //Second check
    if(mybar == NULL)
        return;

    if(mybar->member != NULL)  //Access violation here if I dont have the 'second check'
    {
        //do stuff
    }    
    delete mybar;

    *bar = NULL;

}

我就是这么称呼它的:

Foo *bar = NULL;
initialize(&bar); 
func(&bar);
func(&bar); //Second time I call it, I get the access violation

【问题讨论】:

  • 显示你如何调用函数
  • @claptrap 谢谢,我加了电话。实际上,当我第二次调用它时它会爆炸。我想证明它,这样我才能真正调用它第二次,它只是返回而没有访问冲突。
  • 向你展示initialize()函数。

标签: c++ pointers


【解决方案1】:

那可能是因为你没有检查你的指针是否指向 NULL。

首先检查if(bar== NULL) 说你的指针不是NULL,但是它仍然可以指向一个NULL值(毕竟它只是一个地址) 第二次检查if(mybar == NULL) 完全相同。指针不为空(分配了某个地址),但它仍然可以指向 NULL 值。您没有检查这一点,并且您正在尝试立即访问对象的字段,而这可能是 NULL。

【讨论】:

    【解决方案2】:

    mybar 不必为 NULL 即可导致访问冲突。它可能指向进程地址之外、受保护的内存或其他无效的地方。

    您很可能忘记在代码的其他地方初始化这些指针。

    【讨论】:

      【解决方案3】:

      您的bar 变量永远不会是NULL,因为它不是动态变量。你可能误解了这个定义:

      Foo *bar = NULL;
      

      这里bar 是一个非动态分配的变量,所以&bar 总是(在这个范围内)一个有效的地址。它仅指向NULL 地址。

      假设您在initialiase() 函数中为bar 动态分配了一些内存,那么您的第一个调用将如下所示:

      func(address_of_bar)
      

      在这个函数内部,*bar 指向动态分配的内存(一个有效的、非NULL 地址)。然后通过delete mybar 释放该内存,这又转换为delete *bar

      当您第二次调用func() 时,调用本身保持不变-func(address_of_bar),正如我之前提到的,&bar 在这里始终不是NULL。但是在这个函数内部,*bar == NULL,因为你在第一次调用func() 时已经删除了动态分配的内存。这就是为什么您的第一次检查通过,但第二次失败。

      编辑:为避免这种混淆,我建议对变量和函数参数使用不同的名称,尤其是当它们属于不同类型时(Foo *barFoo **bar)。

      【讨论】:

      • 谢谢!我添加了第一张支票if(bar == NULL || *bar == NULL )
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-19
      • 2017-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      相关资源
      最近更新 更多