2021-10-21 Object Oriented: Dynamically Allocated Memory Block Notes

2021-10-21 Object Oriented: Dynamically Allocated Memory Block Notes

This note is all in the case of VC compiler

new and delete

Complex class:

class Complex
{
    
    
    public : 
        Complex() {
    
    }
    private :
        double m_real;//实部
        double m_imag;//虚部
};
Complex* p = new Complex();

For Complex p = new Complex();* the compiler translates to the following

//1.分配内存,调用malloc(n)函数申请内存
void*mem = operator new(sizeof(Complex));
//2.类型转换
p = static_cast<Complex*>(mem);
//3.构造函数
pc->Complex::Complex(1,2);//Compelx::Complex(pc,1,2),pc一般默认不写,在函数中直接用this来表示
class String
{
    
    
public:                                 
   String(const char* cstr=0){
    
    	
   	    if (cstr) {
    
    
	      m_data = new char[strlen(cstr)+1];
	      strcpy(m_data, cstr);
   	  }else{
    
       
	      	m_data = new char[1];
	      	*m_data = '\0';
   		}
   }                         
   ~String(){
    
    delete[] m_data;}                                   
private:
   char* m_data;
};
String* ps = new String("hello");
delete[] ps;

For *delete[] p;*compiler conversion steps are as follows:

//delete: 先调用析构函数再释放内存
//1.调用析构函数
String::~String();
//2.释放内存
operator delete(ps);//内部调用free()函数

The size of the dynamically allocated memory block

The data part of the Complex has two variables of double type, and the memory size is 8 bytes. The actual memory size applied for under the VC compiler is shown in the figure below

So in debug mode, the total memory size obtained by the pointer p is actually 64 bytes.

In addition to the data part of the Complex class, which has a total of 8 bytes (a double4 byte here), the VC compiler allocates an additional 32+4 bytes in the debug state, and there are two main records at the beginning and end of the entire block of memory information The cookie has a total of 8 bytes, which add up to a total of 52 bytes. Because in the VC compiler, each block given by VC is a multiple of 16, so the total size of the final memory block given is a multiple of 16. Furthermore, 12 bytes will be added here, so that 52 bytes become 64 bytes.

Regarding the memory except the data part of itself, the rest of the memory allocation is not a waste, it is to better reclaim the memory.

About cookie: It is mainly to record the size of the allocated memory, let the system know the size of the entire block of memory to be reclaimed, and it is expressed in hexadecimal numbers. In this example, the size of the entire block of memory is 64 bytes. The hexadecimal conversion is 40, and the last digit becomes 1 to indicate that this memory is allocated. Why is it hexadecimal? Because the size of the memory block is a multiple of 16, the last digit must be 0 if expressed in hexadecimal, so it is convenient to use the last digit to mark whether the memory is allocated.

If it is not in the debugging state, there is no additional allocated 32+4 bytes of memory, as shown in the figure below,
insert image description here
since 16 is a multiple of 16, there is no need to add memory

Array memory size dynamically allocated

Complex* p = new Complex[3];

4 bytes will be added to the memory block to record the number of arrays

array new must be matched with array delete

If you use array new, you must use array delete, otherwise memory leaks will easily occur.
In the dynamic memory allocation of the above class String, use array new, that is, String ps = new String("hello");*, then you must use array delete, that is, delete [] ps .

If delete ps is executed without [], some memory areas pointed to by pointers will not be cleared, resulting in memory leaks.

The memory size allocated when String uses array new is as follows (in non-debug mode):
insert image description here

When using delete is delete ps instead of delete[ ] ps, the destructor is called, and then the inner thickness is released—judging the entire block size of A to be deleted according to the cookie information, so whether there is [ ] at A will be adjusted The block is cleared because the cookie information will not change whether it is array delete or not. However, when there is [], the compiler will know that the destructor needs to be called three times to clear the memory B (a, b, c) obtained by each string object, and if there is no delete, the destructor will only be called once , only A and a are cleared, resulting in the remaining b and c not being cleared, resulting in a memory leak.

Comparing Complex with String, although there is no pointer in Complex* p = new Complex[3] pointing to other memory areas, memory leaks will not occur even if delete p, and the requested memory will be deleted in its entirety based on cookie information, but If you use arrray new, you need to use it with array delete to prevent memory leaks and develop a good habit.

Knowledge source:
Hou Jie C++ object-oriented advanced development: 8. Heap, stack and memory management

Guess you like

Origin blog.csdn.net/weixin_44848852/article/details/120897140