Example code analysis c++ dynamic allocation

  • 2020-09-28 09:01:50
  • OfStack

1. Dynamic allocation and release in c

In c, dynamic memory is requested using malloc and free, these two functions are the standard library functions of c, the memory is allocated using the system call, use them must contain stdlib.h, in order to compile.

After malloc, you need to check whether the memory allocation is successful, but free can only do this if the pointer is not null.

The sample code is as follows:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
 char *p = (char*)malloc(10);
 if ( p == NULL)
 {
 printf("error\n");
 }
 strncpy(p, "23456", sizeof(p)-1);
 printf("p=%s\n", p);
 if ( p != NULL)
 {
 free(p);
 p = NULL;
 }
 return 0;
}

2. c++ Dynamic allocation and release

In c++, the application for dynamic memory USES new and delete, the two keywords that are actually operators, not functions.

It should be noted that if new is not an array, then delete will be used directly and only call the destructor once, while new[] will use delete[] to release, and each element of the array will call the destructor once and then release the memory after the destructor is called.

3. The underlying implementation of new/delete

For basic data types (no need for constructors), new overloads the new operator and calls operator new. For complex data types, the constructor is also called on this basis. In operator new, it is the called malloc function, and if the call to malloc fails, an exception will be thrown.

For basic data types (without destructor), delete overloads the delete operator and calls operator delete. For complex data types, the destructor is also called, while operator delete is the called free function.

4. The underlying implementation of new[]/delete[

Simple data types (including basic data types and types that do not require destructors)
For simple data types, new[] calls operator new[], and operator new is called after calculating the total size of the array. It is worth mentioning that the array can be initialized to zero by (). For example:


char* p = new char[32]();

Is equal to:


char *p = new char[32];
memset(p,0, 32);

For simple data type, delete[] is the same as delete1.

Complex data type

For complex data types, new[] first calls operator new[] to allocate memory, then writes the array size in the first four bytes of the pointer, and then calls the constructor as many times as the number of elements allocated. The reason for writing the array size in the first four bytes is that the destructor for each object is called before freeing memory. But the compiler does not know the actual size of the object p refers to. If the array size is not stored, the compiler does not know how many times the destructor should be called;
The memory allocated by new[] can only be freed by delete[]. If freed by delete it crashes, why does it crash?

Suppose that the pointer p points to the memory allocated by new[], because it needs 4 bytes to store the array size, the actual allocated memory address is [p-4], which is also the address recorded by the system. delete[] actually frees the memory pointed by ES94en-4, while delete will directly release the memory pointed by p. This memory is not recorded by the system at all, so it will crash.

5. What if c++ new fails

According to the new implementation principle mentioned above, in C++, if new fails to allocate memory, the default is to throw an exception. Therefore, if the assignment is successful, p == NULL will never be true; If the allocation fails, if (p == NULL) is not executed because new throws an exception to skip the rest of the code when the allocation fails. If you want to check if new was successful, you should catch an exception:


try {
    int* p = new int[SIZE];
   //  Other code 
} catch ( const bad_alloc& e ) {
   return -1;
}

Of course, the standard C++ also provides a method to suppress new to throw an exception and return a null pointer, as follows:


int* p = new (std::nothrow) int; //  So that if  new  If it fails, it does not throw an exception, but returns a null pointer 
if ( p == NULL ) //  Like this, the judgment makes sense 
return -1;

6. What happens when delete fails? 1

The failure of delete may be due to the fact that delete has passed once before the memory existence, and delete will fail again. The error of linux is: double free or corruption, has been abandoned.

7. Use of placement new

placement new is used to allocate the allocated memory for two more times. The specific implementation is as follows:


// Suppose you have a class X , member function Do() , the code is as follows: 

int main()

{

  char *buf = new char[sizeof(X)];

  X *x = new (buf) X;

  x->Do();

  x->~X(); //1 You must actively call the destructor to destruct 

  delete []buf;

  return 0;

}

Above is the example code analysis c++ dynamic allocation of details, more information about c++ dynamic allocation of other related articles please pay attention to this site!


Related articles: