这是什么问题?悬空指针?

17 浏览
0 Comments

这是什么问题?悬空指针?

可能重复:

返回局部或临时变量的地址

局部变量的内存可以在其作用域外访问吗?

#include
using namespace std;
int *p = NULL;
void fun(void){
    int i = 10;
    p = &i;
}
int main(void){
    fun();
    cout<<*p<

我认为#1和#2会输出相同的结果,但为什么#1输出10而#2输出一个随机数?

0
0 Comments

从上面的内容中可以得出以下结论:

问题出现的原因是,在函数`fun()`返回后,指针`p`变成了一个悬空指针(dangling pointer)。

解决方法可以是在函数`fun()`中,将指针`p`指向的内存空间释放掉。这样可以避免出现悬空指针的情况。

以下是一种可能的解决方法:

void fun() {
    int* p = new int;
    // do something with p
    delete p;
}

在这个示例中,我们在函数`fun()`中使用了`new`关键字来分配一个整数类型的内存空间,并将其赋值给指针`p`。在使用完毕后,我们使用`delete`关键字释放了指针`p`指向的内存空间,从而避免了悬空指针的出现。

总结起来,悬空指针是指在指针指向的内存空间被释放或者回收后,仍然保留着原来的值。这种情况会导致程序访问无效的内存地址,从而引发各种错误。为了避免出现悬空指针,我们应该在使用完毕后,及时释放指针指向的内存空间。

0
0 Comments

在上述内容中,出现了一个问题,即“what's wrong? dangling pointer?”。这个问题的出现是因为在代码中使用了一个指向局部变量的指针,而在该变量超出作用域后继续使用了这个指针。这种情况被称为悬空指针。

悬空指针是一种指向已经释放或超出作用域的内存的指针。当我们试图通过悬空指针访问内存时,由于该内存已经被释放,因此会导致未定义的行为。这意味着程序的行为是不确定的,可能会产生随机的结果。

要解决悬空指针问题,可以采取以下方法:

1. 避免使用指向局部变量的指针。尽量使用指向动态分配内存的指针,或者使用静态变量。

2. 在指针不再需要时,及时将其设置为 NULL 或者释放对应的内存。这样可以避免悬空指针的产生。

3. 在使用指针之前,始终检查其是否为 NULL。这样可以避免在指针为空时访问悬空指针。

例如,在上述代码中,解决悬空指针问题的方法是在变量超出作用域后,将指针设置为 NULL,或者避免使用指向局部变量的指针。

总结起来,悬空指针问题的出现是因为在代码中使用了指向已释放或超出作用域的内存的指针。为了解决这个问题,我们应该避免使用指向局部变量的指针,并在指针不再需要时及时将其设置为 NULL 或释放对应的内存。这样可以避免悬空指针的产生,确保程序的行为是可预测和可控的。

0
0 Comments

这确实是一个悬空指针问题。你将`p`指向一个自动(局部)对象。一旦`fun`函数返回,该对象就不存在了,通过`p`访问它将导致未定义的行为。

如果你对为什么观察到了特定的行为感兴趣:在大多数平台上,`fun`函数的堆栈帧在另一个函数被调用之前仍然存在。因此,在第一次调用`<<`时读取`p`很有可能找到`i`的旧值。调用`<<`之后,旧的堆栈帧很可能已被覆盖,所以读取`p`将找到一个任意的值。但是,这些都不是你可以依赖的行为;访问已经失效的对象可能会导致崩溃或任何其他行为。

对于解释输出可能原因的加一。尽管无法依赖UB,但需要能够识别其影响。

解决这个问题的方法是确保指针`p`指向的对象在使用之前不会被销毁。可以通过将对象分配在堆上或者延长对象的生命周期来解决此问题。以下是一种可能的解决方法:

int* fun() {
    int* p = new int(42);
    return p;
}
int main() {
    int* p = fun();
    std::cout << *p;
    delete p; // 在使用完指针后需要手动释放内存
    return 0;
}

在这个解决方案中,`fun`函数通过`new`运算符在堆上分配了一个`int`对象,并返回指向该对象的指针。在`main`函数中,我们通过调用`fun`函数来获取指向堆上对象的指针,并使用`delete`运算符在不再需要该指针时释放内存。

通过这种方式,我们可以确保对象的生命周期超过函数的执行时间,从而避免了悬空指针问题的发生。

0