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

c++ delete pointer issue, can still access data

本文关键字:访问 数据 删除 指针 问题 c++      更新时间:2023-10-16

我真的不明白为什么这些指针是可访问的…感谢任何帮助

#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;
}

删除指针不会使内存归零,因为这样做会占用CPU周期,而这不是c++的目的。这里有一个悬空指针,还有一个潜在的细微错误。像这样的代码有时可以工作多年,但在将来的某个时候,当程序的其他地方做了一些小的改变时,就会崩溃。

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

这是未定义的行为。任何事情都有可能发生。这次你很幸运。或者可能是不幸的,因为最好得到一个运行时错误!下次你可能会得到一个运行时错误。

解释为什么你会看到未定义行为的特定表现并不是很有用。最好坚持你可以推理的定义良好的行为。

c++不会阻止你向内存中的任意位置写入数据。当您使用newmalloc分配内存时,c++会在内存中找到一些未使用的空间,将其标记为已分配(以便它不会意外地再次分发),并给您它的地址。

一旦你delete内存,然而,c++将其标记为空闲,并可能将其分发给任何需要它的人。您仍然可以对它进行写入和读取,但是此时,其他人可能正在使用它。当您写入内存中的那个位置时,您可能会覆盖您在其他地方分配的一些值。

这里

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

z仍然指向一个内存位置。
但它不再属于你了。你已经把它传递给了delete,并说要处理好这个指针。它的作用与你无关。这就像你卖掉你的车;它仍然存在,但它不是你的,所以打开门往里看可能是可能的,但这可能导致警察逮捕你。

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

delete z;只是释放了z所指向的内存,它并不销毁指针本身。

所以z变成了一个野指针

因为删除内存块并不会使指向该内存块的所有指针的值归零。删除内存只是记录了该内存可用于其他目的。在此之前,内存可能看起来是完整的——但你不能指望它,在一些编译器/运行时/体系结构组合中,你的程序会表现得不同——它甚至可能崩溃。