第十三天(类和动态内存分配·二)

本文深入探讨了C++中使用指针操作对象和动态内存分配的原理,包括构造函数、析构函数的作用及placement new用法的特殊之处。通过实例展示了如何正确释放动态分配的内存,避免内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       今天是来填坑的……

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. 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值