我有一个带有双指针的函数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
答案 0 :(得分:2)
您的bar
变量永远不会是NULL
,因为它不是动态变量。你可能误解了这个定义:
Foo *bar = NULL;
此处bar
是非动态分配的变量,因此&bar
始终(在此范围内)是有效地址。只有点到NULL
地址。
假设您在bar
函数中为initialiase()
动态分配了一些内存,那么您的第一个调用就会显示:
func(address_of_bar)
在此函数内部,*bar
指向动态分配的内存(有效的非NULL
地址)。然后通过delete mybar
释放内存,然后转换为delete *bar
。
当您第二次拨打func()
时,呼叫本身保持不变 - func(address_of_bar)
,正如我之前提到的,&bar
始终为非NULL
。但是在这个函数*bar == NULL
中,因为你第一次调用func()
时已经删除了动态分配的内存。这就是你第一次检查通过的原因,但第二次检查失败了。
编辑:为了避免这种混淆,我建议对变量和函数参数使用不同的名称,尤其是当它们属于不同类型(Foo *bar
vs Foo **bar
)时。
答案 1 :(得分:0)
这可能是因为你没有检查你的指针是否指向NULL。
首先检查if(bar== NULL)
说你的指针不是NULL, BUT 它仍然可以指向一个NULL值(毕竟它只是一个地址)
第二次检查if(mybar == NULL)
完全相同。指针不为空(指定了某个地址),但它仍然可以指向NULL值。你没有检查,你正试图立即访问对象的字段whitch可能是NULL。
答案 2 :(得分:0)
mybar不必为NULL即可导致访问冲突。它可能指向进程地址之外,受保护的内存或其他地方无效。
您很可能忘记在代码中的其他位置初始化这些指针。