c ++删除指针问题,仍然可以访问数据

use*_*948 4 c++ pointers

我真的不明白为什么这些指针可以访问...任何帮助赞赏

#include <iostream>

class Wicked{
public:
    Wicked() {};
    virtual ~Wicked() {};

    int a;
    int b;
};


class Test
{
public:
    Test() {};
    virtual ~Test() {};

    int c;

    Wicked * TestFunc()
    {
        Wicked * z;
        c = 9;
        z = new Wicked;
        z->a = 1;
        z->b = 5;
        return z;
    };
};

int main()
{
    Wicked *z;

    Test *t = new Test();
    z = t->TestFunc();

    delete z;
    delete t;

    // why can I set 'z' when pointer is already destroyed?
    z->a = 10;

    // why does z->a print 10?
    std::cout << z->a << std::endl;

    // why does t->c exist and print correct value?
    std::cout << t->c << std::endl;

    //------------------------------------------------------

    int * p = new int;
    *p = 4;

    // this prints '4' as expected
    std::cout << *p << std::endl;

    delete p;

    // this prints memory address as expected
    std::cout << *p << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 11

这是未定义的行为.什么都有可能发生.这次你很幸运.或者也许是运气不好,因为最好得到运行时错误!下一次可能会遇到运行时错误.

理解为什么你会看到未定义行为的特定表现并不是非常有用.最好坚持你可以推理的明确定义的行为.


Ben*_*enj 11

删除指针不会将任何内存清零,因为这样做会占用CPU周期,这不是C++的意思.你有什么悬挂指针,可能是一个微妙的错误.像这样的代码有时可能会工作多年,只会在将来的某个时候崩溃,因为程序中的其他地方会发生一些小的改动.

当你删除它们指向的内存时,这就是为什么你应该使NULL指针成为一个很好的理由,这样你就会在尝试取消引用指针时立即得到错误.清除使用像memset()这样的函数指向的内存有时也是个好主意.如果指向的内存包含一些您不希望其他(可能是面向用户的)程序部分访问的机密信息(例如明文密码),则尤其如此.

  • NULL指针可能导致隐藏其他类型的错误(可能长时间).最好只使用智能指针,甚至没有进入这种情况.此外,无法保证取消引用NULL指针会产生错误(比其他位置更多),最好不要依赖它来检测错误. (2认同)

Jac*_*nds 6

C++不会阻止你写入内存中的任意位置.当您使用new或分配内存时malloc,C++会在内存中找到一些未使用的空间,将其标记为已分配(以便不会意外地再次分发),并为您提供其地址.

delete然而,一旦你的内存,C++将其标记为免费,并可能将其交给任何要求它的人.您仍然可以写入并从中读取,但此时,其他人可能正在使用它.当您在内存中写入该位置时,您可能会覆盖您在其他位置分配的某些值.


Mar*_*ork 5

这里

// why can I set 'z' when pointer is already destroyed?
z->a = 10;
Run Code Online (Sandbox Code Playgroud)

z 仍然指向内存位置。
但它不再属于你了。您已将其传递给删除并表示要处理该指针。它做什么不再是你关心的事。就像你卖掉你的车一样;它仍然存在,但不是你的,因此打开门并查看可能是可能的,但这可能会导致警察逮捕你。

与删除的指针相同,内存存在但不属于您。
如果您查看内部,它可能会起作用,但也可能会导致分段错误,因为库已刷新页面(您永远不知道)。


Den*_*nis 5

delete z;只是释放指向的内存z,它不会破坏指针本身。

于是就z变成了野指针