The memory development methods we often use are:
inn a=20;//Open up four bytes of space in stack space char arr[]="hdssi";//Open up 10 bytes of continuous space in the stack space
Opening up space on the stack has two characteristics:
- Fixed size
- When declaring an array, you must specify the size of the array and allocate the required memory at compile time
But sometimes I only know the required space when the program is running, so the above methods can not meet our needs. At this time, it can be opened up with dynamic memory
Introduction to dynamic memory functions
malloc and free
Dynamic memory function:
This function requests a continuously available space from memory and returns a pointer to this space.
If the development is successful, a pointer to the developed space is returned.
If the development fails, a NULL pointer is returned, so the return value of malloc must be checked.
The type of the return value is void *, so the malloc function does not know the type of open space, which is determined by the user when using it.
If the parameter size is 0, malloc's behavior is standard and undefined, depending on the compiler.
C language provides another function free, which is specially used for dynamic memory release and recovery. The function prototype is as follows:
The free function is used to free dynamic memory.
If the space pointed to by the parameter memblock is not dynamically opened up, the behavior of the free function is undefined.
If the parameter memblock is a NULL pointer, the function does nothing.
malloc and free function header files are < stdlib. H >.
The free function uses:
#include <stdio.h> int main() { //Code 1 int num = 0; scanf("%d", &num); int arr[num] = {0}; //Code 2 int* ptr = NULL; ptr = (int*)malloc(num*sizeof(int)); if(NULL != ptr)//Determine whether the ptr pointer is null { int i = 0; for(i=0; i<num; i++) { *(ptr+i) = 0; } } free(ptr);//Freeing the dynamic memory pointed to by ptr ptr = NULL;//Is it necessary? return 0; }
C language also provides a function called calloc, which is also used for dynamic memory allocation. The prototype is as follows:
The function is to open up a space for num size elements, and initialize each byte of the space to 0.
The only difference between calloc and malloc is that calloc initializes each byte of the requested space to all zeros before returning the address.
for instance:
int main() { int *p = (int*)calloc(10, sizeof(int)); if(NULL != p) { //Use space } free(p); p=NULL; return 0; }
realloc
The emergence of realloc function makes dynamic memory management more flexible.
Sometimes we find that the space applied for in the past is too small, and sometimes we feel that the space applied for is too large. That's for a reasonable reason
When waiting for memory, we will flexibly adjust the size of memory. Then the realloc function can make a large memory for dynamic development
Small adjustments.
The function prototype is as follows:
memblock is the memory address to be adjusted
New size after resizing
The return value is the adjusted memory starting position.
This function will also move the data in the original memory to a new space on the basis of adjusting the size of the original memory space.
realloc adjusts memory space in two ways:
- There is enough space behind the original space
- There is not enough space after the original space
Case 1
In case 1, to expand the memory, directly add space after the original memory, and the data in the original space will not change.
Case 2
In case 2, when there is not enough space after the original space, the expansion method is to find another appropriate size on the heap space
Continuous space to use. In this way, the function returns a new memory address.
Due to the above two cases, we should pay attention to the use of realloc function.
Common dynamic memory errors
- Dereference operation on NULL pointer
void test() { int *p = (int *)malloc(INT_MAX/4); *p = 20;//If the value of p is NULL, there is a problem free(p); }
- Cross border access to dynamic open space
void test() { int i = 0; int *p = (int *)malloc(10*sizeof(int)); if(NULL == p) { exit(EXIT_FAILURE); } for(i=0; i<=10; i++) { *(p+i) = i;//Cross border access when i is 10 } free(p); } }
- Use free release for non dynamic memory
void test() { int a = 10; int *p = &a; free(p);//no way }
4 use free to release a part of dynamic memory
void test() { int *p = (int *)malloc(100); p++; free(p);//p no longer points to the beginning of dynamic memory
5 release the same dynamic memory multiple times
void test() { int *p = (int *)malloc(100); free(p); free(p);//Repeated release }
Dynamic memory forget release (memory leak)
void test() { int *p = (int *)malloc(100); if(NULL != p) { *p = 20; } } int main() { test(); while(1); }
Forgetting to free dynamic space that is no longer in use can cause memory leaks.