C and C++ dynamic allocation and release of memory differences in detail

  • 2020-04-02 01:44:26
  • OfStack

1. The malloc () function
1.1 malloc is the full name for memory allocation, or dynamic memory allocation.
Prototype: extern void *malloc(unsigned int num_bytes);
Note: allocate a block of memory with the length of num_bytes. If the allocation succeeds, a pointer to the allocated memory is returned, and if the allocation fails, a NULL pointer is returned. When memory is no longer in use, use the free() function to free blocks of memory.

1.2 void * malloc (int size);
Description: malloc to the system application allocation specified size of bytes of memory space, return type is void* type. Void * represents a pointer of an undetermined type. C,C++ states that the void* type can be cast to any other type of pointer.
Note: void* represents a pointer of an undetermined type. More specifically, it means that you do not know what type of data the user is using the space to store when requesting memory space (such as char or int or...).

1.3 free
Void free(void *FirstByte) : this function returns the space previously allocated by malloc to the program or operating system.

1.4 matters needing attention
1) After the memory space is requested, you must check that the allocation was successful.

2) When you no longer need to use the requested memory, remember to release; The pointer to this memory should be NULL after release, in case it is accidentally used later in the program.

3) These two functions should be paired. If not released after the application is a memory leak; If you release without cause, you're doing nothing. You can only release it once, and if you release it twice or more, there will be an error (except when you release a null pointer, you don't do anything with it, so it doesn't matter how many times you release a null pointer).

4) Although the malloc() function is of type (void *) and any pointer of type can be cast to (void *), it is best to cast in the first place as this will avoid some compiler checks.

1.5   Where exactly does malloc() get the memory space?
The answer is to get space in the heap. That is, the function returns a pointer to a block of memory in the heap. The operating system has a linked list of free memory addresses. When the operating system receives a request from the program, it iterates through the list, then looks for the first heap node with more space than the requested node, then deletes the node from the list of free nodes and allocates the node's space to the program.

2. New operator

2.1 in C++, create and release arrays or individual objects dynamically with new and delete.
When we create an object dynamically, we simply specify its data type instead of naming the object, and the new expression returns a pointer to the newly created object that we can access.
Int * PI = new int.
This new expression allocates an integer object in the heap, returns the address of the object, and initializes the pointer PI with that address.

2.2 initialization of dynamically created objects
Dynamically created objects can be initialized by initializing variables.
Int * PI = new int (100); // the object pointed to by the pointer PI is initialized to 100
String * ps = new string (10, '9'); / / * ps as "9999999999"

If display initialization is not provided, class types are initialized with the default constructor of the class. Objects of built-in types are not initialized.
You can also initialize the value of dynamically created objects:
Int * PI = new int (); // is initialized to 0
Int * PI = new int. // PI points to an uninitialized int
String * ps = new string (); // initialized to an empty string (for class types that provide default constructors, there is no need to initialize their objects with values)

2.3 undo dynamically created objects
The delete expression frees the address space to which the pointer points.
Delete the PI; // releases a single object
The delete [] PI; // releases the array
It is illegal to use delete if the pointer does not point to the memory address allocated by new.

2.4 after the delete, reset the value of the pointer
The delete p; // after executing this statement, p becomes an indeterminate pointer. On many machines, although p value is not clearly defined, it still stores the address of the object it refers to before, and then the memory p points to has been freed, so p is no longer valid. At this point, the pointer becomes a dangling pointer (the dangling pointer points to the memory that once held the object, but which no longer exists). Dangling Pointers often cause program errors and are difficult to detect.

Once the object is deleted, set the pointer to 0 immediately, so that the pointer does not point to any object. (null pointer: int * IP =0;)

2.5 distinguish between NULL and NULL Pointers
A null pointer, is a pointer to a value of 0, can be any type of pointer, can be a generic variant type void star can be a char star, int star, etc.

Null pointer, in fact, null pointer is just a programming concept, such as a container may be empty and non-empty two basic states, and in the non-empty may be stored in a value is 0, so the null pointer is artificial pointer does not provide any address information.

2.6 what is returned when a new assignment fails?
Until 1993, c++ required an operator in case of a memory allocation failure     New returns 0, and now requires the operator     New throws an STD ::bad_alloc exception. Many c++ programs were written before the compiler started supporting the new specification. The c++ standards board didn't want to give up code that already followed the return 0 specification, so they provided another form of operator     New (and operator     New []) to continue to provide the return 0 function. These forms are called "no-throw" because they don't use a throw, but instead use a nothrow object at the entry point where new is used:
The class     The widget     {     .     };

The widget     * pw1     =     The new     The widget. //     An allocation failure throws STD ::bad_alloc    

The if     (pw1     = =     0)     . //     This check must fail

The widget     * pw2     =     The new     (nothrow)     The widget.     //     Returns 0 if the assignment fails

The if     (pw2     = =     0)     . //     This check is likely to succeed

3. The difference between malloc and new

3.1 new returns a pointer to the specified type and can automatically calculate the required size.
Such as:
1) Int * p;
P = new int. // return type int* (integer pointer), allocate size to sizeof(int);
Or:
Int * parr;
Parr = new int [100]; // return type int* (integer pointer), allocate size sizeof(int) * 100;

2) Malloc, on the other hand, has to count the number of bytes by us and force it to convert to a pointer of the actual type upon return.
Int * p;
P = (int *) malloc (sizeof(int)*128); // assign 128 (which can be replaced as needed) integer storage units, and store the first address of the 128 consecutive integer storage units in the pointer variable p  
Double *pd=(double *) malloc (sizeof(double)*12); // allocate 12 double storage units and store the first address in the pointer variable pd

3.2 malloc allocates memory, but does not initialize the resulting memory, so the value of the resulting new piece of memory will be random.
Get the pointer through malloc or new and be consistent with other operations, except for the different methods of allocation and final release.

4. Why new/delete when you have malloc/free?

1) Malloc and free are standard library functions for C++/C, and new/delete are C++ operators. Both can be used to request dynamic memory and free memory.

2) For objects with non-internal data types, maloc/free alone cannot satisfy the requirements of dynamic objects. The constructor is executed automatically when the object is created, and the destructor is executed automatically before the object dies. Since malloc/free is a library function, not an operator, and is not within the compiler's control, you cannot impose the task of performing constructors and destructors on malloc/free.

So the C++ language needs an operator new to do dynamic memory allocation and initialization, and an operator delete to clean and free memory. Note that new/delete is not a library function.

Instead of trying to use malloc/free for dynamic object memory management, we should use new/delete. Since the "objects" of the internal data types have no construction or destruction process, malloc/free and new/delete are equivalent for them.

3) Since new/delete fully covers malloc/free, why doesn't C++ eliminate malloc/free? This is because C++ programs often call C functions, and C programs can only manage dynamic memory with malloc/free.

If you release the "dynamic object created by new" with free, the object may fail to execute the destructor and cause an error in the program. If you release "malloc requested dynamic memory" with delete, the result will also be an error, but the program is poorly readable. So new/delete has to be paired, as does malloc/free.


Related articles: