0

我有一个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
4

3 回答 3

2

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

Foo *bar = NULL;

bar是一个非动态分配的变量,因此&bar(在此范围内)始终是有效地址。它只指向NULL地址。

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

func(address_of_bar)

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

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

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

于 2013-10-24T08:12:45.310 回答
0

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

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

于 2013-10-24T07:17:20.813 回答
0

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

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

于 2013-10-24T07:26:30.750 回答