This is a summary I have just learned from programming. It mainly comes from a book named "High Quality C/C ++ programming". After many years, I will review it.
1. malloc ()
The malloc () function is used to allocate memory: Pass the total number of bytes required as a parameter to the function. The returned value is a pointer to the latest memory allocation. If the memory is not allocated properly, the return value is null.
The Usage Technology of malloc:
Some_type * pointer;
Pointer = malloc (count * sizeof (* pointer ));
Note:
(1) This method ensures that malloc () allocates the correct amount of memory without considering the pointer's life. If the pointer type changes later, the sizeof operator automatically ensures that the number of bytes to be allocated is still correct.
(2) The memory returned by malloc () is "not initialized. This memory may contain any random garbage. You can use valid data immediately or at least use zero to initialize this memory. Initialize with 0. You can use
Void * memset (void * s, int C, size_t N );
(3) malloc () original data in the physical memory obtained by page missing exception in most cases, which is 0 (but cannot be guaranteed to be 0)
2. calloc ()
The calloc () function is a simple package of malloc. Its main advantage is to clear the dynamically allocated memory.
Void * calloc (size_t nmemb, size_t size );
Experienced programmers prefer to use calloc (), because in this case, the newly allocated memory content will not have any problems. Calling calloc () will certainly clear 0 and avoid calling memset ().
3. realloc ()
Function prototype: extern void * realloc (void * mem_address, unsigned int newsize); # include <stdlib. h> Some compilers need # include <alloc. h>. Change the size of the memory area referred to by mem_address to the newsize length. If the reallocation succeeds, the pointer pointing to the allocated memory is returned. Otherwise, the NULL pointer is returned. When the memory is no longer used, use the free () function to release the memory block.
Note: The data in the original memory remains unchanged.
4. malloc () and calloc ()
Both the malloc () and calloc () functions can be used to dynamically allocate memory space, but the two functions are slightly different:
(A) the malloc () function has a parameter, that is, the size of the memory space to be allocated:
Void * malloc (size_t size );
The calloc () function has two parameters: the number of elements and the size of each element. The product of these two parameters is the size of the memory space to be allocated.
Void * calloc (size_t numelements, size_t sizeofelement );
(B) if the call is successful, both the malloc () function and calloc () function will return the first address of the allocated memory space.
(C) The main difference between the malloc () and calloc () functions is that the former Cannot initialize the allocated memory space, while the latter can.
(D) if the memory space allocated by the malloc () function has not been used before, each of them may be 0; otherwise, if the memory has been allocated, there may be a variety of data. That is to say, when the program using the malloc () function starts (the memory space has not been re-allocated), it can work normally, but after a period of time (the memory space has been re-allocated) problems may occur.
(E) The calloc () function initializes every bit in the allocated memory space to zero. That is to say, if you allocate memory for elements of the character or Integer type, these elements are always initialized to 0; if you allocate memory for pointer elements, these elements are usually initialized to a null pointer; if you allocate memory for real data, these elements will be initialized to zero of the floating point type.
(F) calloc (m, n) is essentially equivalent
P = malloc (M * n );
Memset (p, 0, M * n );
5. Free and delete
(A) They only release the memory indicated by the pointer, but do not kill the pointer itself.
(B) After p is free, its address remains unchanged (not null), but the memory corresponding to this address is junk, and p becomes a "wild pointer ". If P is not set to null at this time, it is mistaken that p is a valid pointer.
(C) Sometimes we cannot remember whether the memory referred to by P has been released. Before we continue to use P, we usually use the statement if (P! = NULL. However, if (P! = NULL.
6. New and malloc
(1) New is the operator in C ++, and malloc is a function in C.
(2) New not only allocates memory, but also calls class constructor. Similarly, delete calls class destructor, while malloc only allocates memory, does not initialize class members, or free does not call destructor.
(3) Memory leakage can be checked out for both malloc and new. The difference is that new can indicate the row of the file, but malloc does not.
(4) Comparison of new and malloc Efficiency
(A) New can be considered as the execution of the malloc and constructor.
(B) The new pointer directly carries the type information, while the malloc returns the void pointer.
7. New/delete and malloc/free
(A) New/delete is an operator, and malloc/free is a function.
(B) malloc and free are standard library functions of C ++/C, and new/delete are operators of C ++. They can be used to apply for dynamic memory and release memory.
(C) For non-Internal data objects, maloc/free alone cannot meet the requirements of dynamic objects. The constructor must be automatically executed when the object is created, and the number of destructor must be automatically executed before the object is extinct. Since malloc/free is a library function rather than an operator and is not controlled by the compiler, it is impossible to impose the tasks of executing constructor and destructor on malloc/free.
(D) Do not use malloc/free to manage the memory of dynamic objects. Use new/Delete. Because the internal data type "object" does not have a process of construction and analysis, malloc/free and new/delete are equivalent to them.
(E) The C ++ language requires a new operator capable of dynamic memory allocation and initialization, and a delete operator capable of cleaning and releasing memory. Note that new/delete is not a database function.
(F) New Delete actually calls the malloc and free functions in implementation. In addition to memory allocation, new operator also calls constructors. the malloc function is only responsible for memory allocation.
(G) Since the new/delete function completely covers malloc/free, why does C ++ not eliminate malloc/free? This is because C ++ programs often call C functions, and C Programs can only use malloc/free to manage dynamic memory. If you use free to release the "New Dynamic Object", this object may cause program errors because it cannot execute the destructor. If you use Delete to release the "dynamic memory applied by malloc", theoretically, the program will not go wrong, but the program is poorly readable. Therefore, new/delete must be paired, and the same applies to malloc/free.
8. Usage of malloc/free
(A) malloc only cares about two elements: "type conversion" and "sizeof"
(B) the malloc function does not identify the type of memory to be applied for. It only cares about the total number of bytes of memory.
(C) the return value type of malloc is void *. Therefore, you must explicitly convert the type when calling malloc and convert void * to the required pointer type.
(D) The reason why the free (p) statement can correctly release the memory is that the pointer p type and the memory capacity it refers to are known in advance. If P is a null pointer, no matter how many times the free P operation will fail. If P is not a null pointer, the free operation on P will cause a program running error.
9. Usage of new/delete
(A) The new operator is much easier to use than the malloc function, because new has built-in sizeof, type conversion, and type security check functions. For non-Internal data objects, new completes initialization while creating dynamic objects. If an object has multiple constructors, the new statement can also have multiple forms.
For example:
Int * P1 = (int *) malloc (sizeof (INT) * length );
Int * P2 = new int [length];
(B) If you use new to create an object array, you can only use the non-parameter constructor of the object.
OBJ * objects = new OBJ [100]; // create 100 Dynamic Objects
(C) When releasing an array of objects using Delete, do not lose the symbol "[]". Delete [] objects; // correct usage
10. Wild pointer
-- The "wild Pointer" is not a null pointer, but a pointer to the "junk" memory. Generally, null pointers are not incorrectly used, because if statements are easy to judge. However, the "wild Pointer" is very dangerous, and the IF statement does not work for it.
There are two main causes of "wild pointer:
(A) the pointer variable is not initialized. When a pointer variable is created, it does not automatically become a null pointer. Its default value is random, which means it is random. Therefore, the pointer variable should be initialized at the same time when it is created, either set the pointer to null or set it to direct to the legal memory.
(B) After the pointer P is free or deleted, It is not set to null, which makes people mistakenly think P is a valid pointer.
(C) pointer operations go beyond the scope of variables. This situation is hard to prevent,
11. Memory Allocation Method
There are three memory allocation methods:
(A) Distribution from the static storage area. The program has been allocated when it is compiled, and the program exists throughout the entire runtime. For example, global variables and static variables.
(B) Create a stack. When a function is executed, the storage units of local variables in the function can be created on the stack. When the function is executed, these storage units are automatically released. Stack memory allocation computation is built into the processor's instruction set, which is highly efficient, but the memory capacity allocated is limited.
(C) Allocate from the stack, also known as dynamic memory allocation. When the program runs, it uses malloc or new to apply for any amount of memory. The programmer is responsible for releasing the memory with free or delete. The lifetime of the dynamic memory is determined by us. It is very flexible to use, but the problem is also the most.
** Common memory errors and Countermeasures
1. The memory allocation fails, but it is used.
New programmers often make this mistake because they do not realize that memory allocation will fail. A common solution is to check whether the pointer is NULL before using the memory. If the pointer p is a function parameter, use assert (p! = NULL. If you use malloc or new to apply for memory, you should use if (p = NULL) or if (p! = NULL.
2. Although the memory allocation is successful, it is referenced before initialization.
There are two main causes for this mistake: first, there is no idea of initialization; second, the default initial values of the memory are all zero, resulting in incorrect reference values (such as arrays ).
There is no uniform standard for the default initial values of the memory. Although sometimes it is zero, we prefer to trust it without any trust. Therefore, no matter which method is used to create an array, do not forget to assign the initial value. Even the zero value cannot be omitted, so do not bother.
3. The memory has been allocated successfully and initialized, but the operation has crossed the memory boundary.
For example, when an array is used, the subscript "more than 1" or "less than 1" is often performed. Especially in for loop statements, the number of loops is easy to make a mistake, resulting in array operations out of bounds.
4. I forgot to release the memory, causing memory leakage.
A function containing such errors loses a piece of memory every time it is called. At the beginning, the system had sufficient memory and you could not see the error. Once a program suddenly died, the system prompts: memory is exhausted.
Dynamic Memory application and release must be paired. The usage of malloc and free in the program must be the same, otherwise there must be an error (the same applies to new/delete ).
5. The memory is released, but it is still used. (There are three situations :)
(1) The object calling relationship in the program is too complex, so it is difficult to figure out whether an object has released the memory. At this time, we should re-design the data structure to fundamentally solve the chaos of Object Management.
(2) The return Statement of the function is incorrect. Be sure not to return the "Pointer" or "Reference" pointing to "stack memory" because the function body is automatically destroyed when it ends.
(3) After the memory is released using free or delete, the pointer is not set to NULL. As a result, a "wild pointer" is generated ".
** Notes for correction:
(A) after applying for memory with malloc or new, check whether the pointer value is NULL immediately. Prevents the use of memory with NULL pointer values.
(B) do not forget to assign initial values to arrays and dynamic memory. Avoid using uninitialized memory as the right value.
(C) Avoid overthrowing the subscript of an array or pointer, especially when "more than 1" or "Less 1" is performed.
(D) The application and release of dynamic memory must be paired to prevent memory leakage.
(F) after the memory is released with free or delete, the pointer is immediately set to NULL to prevent "wild pointer ".
12. Comparison between pointers and Arrays
(A) pointers and arrays can be replaced in many places, but they are not equivalent!
(B) arrays are either created in static storage areas (such as global arrays) or on stacks. The array name corresponds to (rather than pointing to) a piece of memory, and its address and capacity remain unchanged during the lifetime, only the content of the array can be changed.
(C) A pointer can point to any type of memory block at any time. It features "mutable", so we often use pointers to operate dynamic memory. Pointers are far more flexible than arrays, but they are more dangerous.
(D) If you want to copy the content of array a to array B, you cannot use statement B = a. You should use the standard library function strcpy for copying.
(F) compare whether the content of B and a is the same. if (B = a) cannot be used to determine whether to use the standard library function strcmp for comparison.
(G) Statement p = a does not copy the content of a pointer p, but assigns the address of a to p. You can use the library function malloc to apply for a memory with a capacity of strlen (a) + 1 characters for p, and then use strcpy to copy strings.
The (h) statement if (p = a) compares not the content but the address. It should be compared using the database function strcmp.
(I) the sizeof operator can be used to calculate the array capacity (number of bytes) (do not forget '\ 0 ').
(J) C ++/C language cannot know the memory capacity referred to by the pointer unless you remember it when applying for memory.
(K) Note that when an array is passed as a function parameter, the array will automatically degrade to a pointer of the same type. (That is, the essence of using an array name in a function is the corresponding pointer ).
13. pointer parameter transfer memory
(A) If the function parameter is a pointer, the pointer cannot be used to request dynamic memory.
(B) If you have to use pointer parameters to request memory, you should use "pointer to Pointer" instead ".
Void GetMemory2 (char ** p, int num) {* p = (char *) malloc (sizeof (char) * num);} void Test2 (void) {char * str = NULL; GetMemory2 (& str, 100); // note that the parameter is & str, not str strcpy (str, "hello "); cout <str <endl; free (str );}
(C) because the concept of "pointer to Pointer" is not easy to understand, we can use function return values to transmit dynamic memory. This method is simpler.
char *GetMemory3(int num){ char *p = (char *)malloc(sizeof(char) * num); return p;}void Test3(void){ char *str = NULL; str = GetMemory3(100); strcpy(str, "hello"); cout<< str << endl; free(str);}
14. Handle memory depletion issues
If a large enough memory block cannot be found when applying for dynamic memory, malloc and new will return a NULL pointer, declaring that the memory application failed. There are usually three ways to handle the "memory depletion" Problem
(A) judge whether the pointer is NULL. If yes, use the return statement to terminate the function immediately.
void Func(void){A *a = new A;if(a == NULL){ return; }…}
(2) judge whether the pointer is NULL. If yes, use exit (1) to terminate the entire program. For example:
void Func(void){A *a = new A;if(a == NULL){cout << “Memory Exhausted” << endl; exit(1);}…}
(3) set exception handling functions for new and malloc. For example, in Visual C ++, you can use the _ set_new_hander function to set your own exception handling function for new, or enable malloc to use the same exception handling function as new. For more information, see the C ++ user manual.
** (1) (2) is the most common method. If a function needs to apply for dynamic memory in multiple places, the method (1) is insufficient (it is troublesome to release the memory) and should be handled in the way (2.
Sherwin sorting of Jiangxi University of Science and Technology