Why should I not try to use “this” value after “de

2019-01-02 21:36发布

In this paragraph of C++ FAQ usage of delete this construct is discussed. 4 restrictions are listed.

Restrictions 1 to 3 look quite reasonable. But why is restriction 4 there that I "must not examine it, compare it with another pointer, compare it with NULL, print it, cast it, do anything with it"?

I mean this is yet another pointer. Why can't I reinterpret_cast it to an int or call printf() to output its value?

7条回答
呛了眼睛熬了心
2楼-- · 2019-01-02 21:39

because any action you can take with that pointer could trigger logic which is interpreted on the class methods of that object, which could lead to a crash.

Now, some of the actions you point at could be apparently "safe", but it's difficult to say what happens within any method you can call.

From the post: "must not examine it, compare it with another pointer, compare it with NULL, print it, cast it, do anything with it"?

All these actions can trigger operator related functions, which are evaluated with an undefined pointer. Idem for casting.

Now if you perform a reintepret_cast, that's probably a different story, and you could probably get along with it, as reinterpret is just a bit by bit reinterpretation, without involving (as far as I know) any method call.

查看更多
呛了眼睛熬了心
3楼-- · 2019-01-02 21:42

b/c the address that this refers to now, it undefined, and you don't know what might be there...

查看更多
孤独总比滥情好
4楼-- · 2019-01-02 21:53

In a multi-threaded program, the moment you delete a pointer, the free space can be allocated by another thread, overwriting the space used by this. Even in a single-thread program, unless you're very careful about what you call before returning, anything you do after delete this could allocate memory and overwrite what used to be pointed to by this.

In a Microsoft Visual C++ executable compiled in Debug mode, deleteing a pointer causes its memory to be immediately overwritten with a 0xCC test pattern (uninitialized variables are also initialized with this pattern), to help in identifying dangling pointer bugs such as this one.

This reminds me of when I fixed a bug in a online-playable game in which a Fire object's constructor deleted the oldest Fire if the total number of Fires had reached a certain number. The deleted Fire was sometimes the parent Fire creating a new Fire — bam, dangling pointer bug! It was only due to luck that this bug interacted with the memory allocation algorithm in a completely predictable way (the deleted Fire was always overwritten with a new Fire in the same way) — otherwise it would have caused a desynchronization between online players. I found this bug when rewriting the way the game did memory allocation. Due to its predictability, when I fixed it, I was also able to implement emulation of its behavior for compatibility with older game clients.

查看更多
素衣白纱
5楼-- · 2019-01-02 21:56

Aha!

3.7.3.2/4: "... the deallocation function shall deallocate the storage referenced by the pointer, rendering invalid all pointers referring to any part of the deallocated storage. The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined".

Note that this says "using the value", not "dereferencing the pointer".

That paragraph is not specific to this, it applies to anything that has been deleted.

查看更多
唯独是你
6楼-- · 2019-01-02 21:58

For the same reason you would not delete any other pointer and then try and perform any operations on it.

查看更多
永恒的永恒
7楼-- · 2019-01-02 22:01

The reason that you cannot do anything with a pointer after you delete it (this, or any other pointer), is that the hardware could (and some older machines did) trap trying to load an invalid memory address into a register. Even though it may be fine on all modern hardware, the standard says that the only thing that you can do to a invalid pointer (uninitialized or deleted), is to assign to it (either NULL, or from another valid pointer).

查看更多
登录 后发表回答