为什么不访问删除的对象会使我的程序崩溃? [英] Why isn't accessing a deleted object crashing my program?

查看:90
本文介绍了为什么不访问删除的对象会使我的程序崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一段代码正在创建基于图块的关卡.

I have a piece of code that is creating a tile based level.

class Level {

//Variables
//===================================================
public:
    Tile *** TileGrid;  //A 2d array of pointers to tiles
    int TilesWide, TilesTall;

//Methods
//===================================================
public:
    Level::Level(char * fileName);
    Level::~Level();
    void Draw();
};

我为TileGrid分配了内存,一切都很好.我也为该类设置了析构函数.

I allocate memory for the TileGrid and all is good. I have a destructor set up for the class too.

Level::~Level() {

    for (int i = 0; i < TilesTall; i++) {
        for (int j = 0; j < TilesWide; j++)
            //delete the looped tile being pointed to
            delete TileGrid[i][j];

        //delete the row
        delete [] TileGrid[i];
    }

    //delete the array of rows
    delete [] TileGrid;
}

对于傻笑,我决定删除我的Level实例.这样做之后,我发现我仍然可以调用它的Draw方法.

For giggles I decided I would delete my instance of Level. After I did so, I found that I could still call its Draw method.

在调试器中,TilesWide和TilesTall的值是一个很大的负数,因此在迭代网格的for循环中没有画任何东西.

In the debugger the values for TilesWide and TilesTall are a huge negative numbers, so nothing draws in my for loops iterating the grid.

尝试访问已删除的变量不会导致某种崩溃吗?

Would trying to access a deleted variable not cause some sort of crash?

推荐答案

您所做的事情被称为未定义行为".

What you have done is known as "Undefined behavior".

未定义的行为并不意味着将崩溃",这意味着任何事情都可能发生.该程序可以格式化您的硬盘,可以播放巴赫奏鸣曲,可以在屏幕上绘制达菲鸭的图片,可以为您提供负值,并且在每种情况下都可以精确地显示 您要的是什么.

And undefined behavior doesn't mean "will crash", it means anything can happen. The program could format your hard drive, it could play a Bach sonata, it could draw a picture of daffy duck on the screen, it could give you a negative value, and in every case it would be exactly what you asked for.

包括不崩溃以及崩溃.

现在让我们假设一个合理合理的C ++实现.方法Level::Draw随传递的Level实例而变化,因此,调用的函数不依赖于该实例.实例作为参数传递给该函数,并作为指针指向堆中曾经用作变量副本的内存.从那时起,它已被回收再用于其他目的,或者可能包含有关堆的簿记信息-那里没有定义. (而且,如果运行时将页面返回到系统,则访问它可能会出现段错误)

Now let us suppose a reasonably sane implementation of C++. The method Level::Draw does not vary with which instance of Level you pass it, so what function you call doesn't rely on the instance. The instance is passed as a parameter to this function as a pointer that points to some memory in the heap that used to be a copy of the variable. Since then, it has been recycled for some other purpose, or maybe contains book-keeping information about the heap -- what is there is undefined. (And, accessing it could segfault if the runtime returned the page to the system)

然后,您将这些垃圾解释为某些值.一切都很好,因为在大多数系统上,随机垃圾看起来总是像C ++ int eger(在这种情况下,为负整数).

You then proceed to interpret that garbage as some values. Things are perfectly fine, because random garbage looks like a C++ integer (in this case, as a negative integer) pretty much always on most systems.

现在,一旦开始取消引用指针(这样,访问内存的随机"部分)或写入this状态,就很可能发生崩溃(如果不是,则崩溃,然后再崩溃,或在其他地方发生)

Now, once you start dereferencing pointers (and as such, accessing "random" parts of memory), or writing to the state of this, crashing is likely to happen (if not then, then later, or elsewhere).

这篇关于为什么不访问删除的对象会使我的程序崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆