c, c++ summary - dynamic memory management

Before introducing dynamic memory management, let me say a few words about memory. Students who often write code know that memory is mainly divided into three types:

Static area, heap and stack

The static area mainly stores some static global variables. The content of the static area exists during the entire program running, and is destroyed when the program runs. Since it is specified before the program runs, there is no way for the program to modify it.

A stack is also called a stack. It mainly stores some local variables and function parameters. Destroyed immediately after the function finishes running. A remarkable feature of the stack is that it is efficient but not much space.

Heap : A section of space allocated by malloc/new. This space needs to be released manually by free/delete, otherwise it is easy to cause memory leaks. It is relative to the stack. The usable space is much larger, but it is not safe as it often causes memory leaks.




Several situations of typical memory leaks:

a. The memory has not been successfully applied, start using it

b. The memory application is successful, but not initialized

c. The memory is not released after use

d. Only part of the memory is released




The same is to open up a memory space, the difference between malloc/calloc/ralloc is subtle:

void* malloc(unsigned size);

malloc opens up a contiguous memory space of size bytes on the heap.

void* calloc(size_t n, size_t elsize);

 calloc allocates n memory spaces of size size bytes and initializes the contents of each space to 0.

void* realloc(void* ptr, unsigned newsize);

realloc releases the contents of the original ptr, then allocates newsize bytes of space, and finally copies the original data to the newly allocated memory space.





Next, let's look at the difference between malloc/free and new/delete:

a. malloc/new are two library functions of standard c language. new/delete are two operators in C++. Their role is to dynamically manage a memory space.

For data of non-standard data types, it needs to call the constructor when it is created and the destructor when it is released. Since the compiler cannot manage the inside of the function body, at this time, malloc/new cannot meet the requirements. At this time, new/delete is needed to complete the construction and destruction work for us.

b. The space requested by malloc requires us to manually calculate the required size. And new will calculate the required memory size by the system itself.

c. The new operator is type-safe and returns a pointer of the object type, which strictly matches the object and does not require type conversion. The successful return of malloc allocation is void*, which requires us to convert void* to the type we need by casting.

int* p1 = (int*)malloc(sizeof(int));  
int* p2 = new (int);

d. NULL will be returned after malloc allocation fails, and an exception will be thrown after new allocation failure, and NULL will not be returned.

Our code habit in the c language part is to compare the memory space with NULL after malloc, and the allocation is successful if it is not empty. But this habit is useless when it comes to new. Because if the program can be executed down, it means that the allocation has been successful, otherwise an exception will be thrown. At this time, if we want to see whether new successfully allocates space, we need to use the exception mechanism.

e. new/delete will call the object's constructor/destructor to complete the object's construction/destruction. while malloc does not

When new/delete is used to dynamically create an array, int* p = new int[6]; will call the constructor 6 times. . . Similarly, delete[] p will also call the destructor 6 times.

There are three steps when using the new operator to allocate object memory:

  • Step 1: Call the operator new function (operator new[] for arrays) to allocate a large enough raw , unnamed memory space to store objects of a specific type.
  • Step 2: The compiler runs the corresponding constructor to construct the object and passes in the initial value for it.
  • Part 3: After the object is constructed, a pointer to the object is returned.

There are two steps when using the delete operator to free object memory:

  • Step 1: Call the object's destructor.
  • Step 2: The compiler calls the operator delete (or operator delete[]) function to release the memory space.

f.new/delete can be overloaded, but malloc/free cannot.

g. malloc/free, new/delete, new[]/delete[] must be used in pairs, otherwise it will also cause memory leaks.




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325980703&siteId=291194637