第十三天(類和動態內存分配·二)

       今天是來填坑的……

2011-11-14(Classes and Dynamic Memory Allocation II)
1. Using Pointer to Objects
C++ programs often use pointers to object. If ClassName is a class and value is of type TypeName, The following statements:
                   ClassName* ob = new ClassName(value);
                   ClassName* ob = new ClassName;

invokes this constructor:
                   ClassName(TypeName);
                   ClassName();
//default constructor
That is a little subtle. Here, the programmers use new to create objects, which does the same job of constructors. But an object is also a kind of “object” that needs a chunk of memory to store. This allocates space not for the content of object but for itself— that's for the str pointer that holds the address of the string and for the len member but not for static members in the case of String class. So you are supposed to use delete to free what the pointer ob point to without brackets, like: 
                   delete ob; //not delete[] ob
If delete operator applied to the object pointer ob, destructor of which will be called automatically.
     Again, destructors are called in the following situations:
          #     If an object is an automatic variable, the object's destructor is called when the program exits the block in which is defined.
          #     If an object is a static variable, destructor is called when the program terminates.
          #     If an object is created by new, its destructor is called only when you explicitly use delete on the object.
2. Looking again at Placement new
Using placement new with object adds some twists. Let's think about the following short code: 

char* buffer = new char[512];
String s1 = new (buffer) String("String one");
String s2 = new (buffer) String("String two");
delete[] buffer;
We assume that the class String is a complete class(at least has constructor and destructor).
       Two obscure problems:
I. After executing line 3, s1 is disappear.
Believe it or not, if you print s1, the result would be "String two". That's because when creating a second object, placement new simply overwrites the same location used for the first object. What's worse, you can't find s1, meanwhile this useless data is still occupies the memory allocated just now. But why? Why destructor did anything about it? Destructor isn't the God, it doesn't know anything about what placement new does with the 512-byte block.
         One solution is to make sure that the locations don't overlap:
                   String s2 = new (buffer + sizeof(s1)) String ("String two");
II. new without delete .
Last line, the statement: delete[] buffer; can't free the memory of s1 and s2. It just free the the memory of object's members. For objects created on the heap, you can use this:
                   delete pointerToOb;
And destructor will be called automatically. But you can't use this:
                                         delete s1, s2;  
That is because the address value of s1, s2 and buffer are equal. This statement is equals to delete buffer; which isn't matching the allocation statement: 

                   char* buffer = new char[512]; 
The solution is to call to destructor explicitly:
                   s1->~String();
                   s2->~String();

to free the memory of s1 and s2. 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章