The meaning of static in C++

I thought I was fairly good with C++, it turns out that I'm not. A previous question I asked: C++ const lvalue references had the following code in one of the answers:


#include <iostream>
using namespace std;

int& GenX(bool reset) { static int* x = new int; *x = 100; if (reset) { delete x; x = new int; *x = 200; } return *x; }

class YStore { public: YStore(int& x); int& getX() { return my_x; } private: int& my_x; };

YStore::YStore(int& x) : my_x(x) { }

int main() { YStore Y(GenX(false)); cout << "X: " << Y.getX() << endl; GenX(true); // side-effect in Y cout << "X: " << Y.getX() << endl; return 0; }

The above code outputs X: 100, X:200. I do not understand why. I played with it a bit, and added some more output, namely, a cout before the delete x; and a cout after the new x; within the reset control block.

What I got was: before delete: 0x92ee018 after new: 0x92ee018

So, I figured that static was silently failing the update to x, and the second getX was playing with (after the delete) uninitialized memory; To test this, I added ax = 0; after the delete, before the new, and another cout to ensure that x was indeed reset to 0. It was.

So, what is going on here? How come the new returns the exact same block of memory that the previous delete supposedly free'd? Is this just because that's what the OS's memory manager decided to do, or is there something special about static that I'm missing?

Thank you!


That's just what the memory manager decided to do. If you think about it, it makes a lot of sense: You just freed an int, then you ask for an int again... why shouldn't the memory manager give you back the int you just freed?

More technically, what is probably happening when you delete is that the memory manager is appending the memory block you freed to the beginning of the free list. Then when you call new , the memory manager goes scanning through its free list and finds a suitably sized block at the very first entry.

For more information about dynamic memory allocation, see "Inside storage allocation".


To your first question:

X: 100, X:200. I do not understand why.

Since Y.my_x is just a reference to the static *x in GenX , this is exactly how it supposed it to be - both are referencing to the same address in memory, and when you change the content of *x, you get a side effect.


You are accessing the memory block that is deallocated. By the c++ standard, that is an undefined behaviour, therefore anything can happen.

EDIT

I guess I have to draw :

  • You allocate the memory for an int, and you pass the object allocated on the heap to the constructor of Y, which stores that in the reference
  • then you deallocate that memory, but your object Y still holds the reference to the deallocated object
  • then you access the Y object again, which holds an invalid reference, referencing deallocated object, and the result you got is the result of an undefined behaviour.
  • EDIT2

    The answer to why : implementation defined. The compiler can create new object at any location it likes.

    链接地址: http://www.djcxy.com/p/85064.html

    上一篇: c ++ mysql sqlstring崩溃0xC0000005无法读取内存

    下一篇: 静态在C ++中的含义