Dynamic memory management
The meaning of existence
Our memory development methods are mainly:
int a=0;//开辟4字节的空间
int arr[5]={
0};//开辟20字节的空间
There are several problems with this development:
Since the variable development is in the stack in the memory, the space is relatively limited.
It can only open up a fixed memory space, which is not convenient for subsequent adjustments.
In a specific scenario, we cannot obtain the memory size that needs to be opened up.
Therefore, we have dynamically opened up space to solve problems in some specific situations.
1. Unable to determine the required memory size, or a changed memory size
2. You can open up a larger space for operation (the dynamically opened memory space is on the memory heap, and the space is larger than the stack space where the variable is located)
3. But although it is very Good, but the dynamically opened memory space needs to be released actively by the person we applied for, otherwise it will cause serious memory leaks.
Memory leak can be said to be a very fatal problem, especially in some continuous running places, such as server code. In severe cases, the server will be paralyzed.
- Stack: When a function is executed, the storage units of local variables in the function can be created on the stack, and these
storage units are automatically released when the function is executed . The stack memory allocation operation is built into the processor's instruction set, which is very efficient, but the allocated memory capacity is
limited. The stack area mainly stores local variables, function parameters, return data, return addresses, etc. allocated for running functions.- Heap: Generally allocated and released by the programmer, if the programmer does not release it, it may be reclaimed by the OS when the program ends. The allocation method is similar
to a linked list.
related functions
1.malloc
C language provides a function for dynamic memory development:
void* malloc(size_t size);
//size是指开辟空间的字节数
This function applies for a continuously available space from the memory and returns a pointer to this space.
1. If the development is successful, a pointer to the opened space will be returned. Return NULL on failure;
2. The return value is generic, so we can decide by ourselves.
3. If the parameter size is 0, the behavior of malloc is undefined by the standard.
We generally use malloc like this:
int* arr=(int*)malloc(4);
int a[5]={
0};
char* arr1=(char*)malloc(sizeof(int)*5);
//malloc搭配sizeof更方便
//malloc一般使用是带一个强制类型转换
2.free
The C language provides another function free, which is specially used for the release and recovery of dynamic memory. The function prototype is as follows:
void free(void*arr);
Key points:
The free function is used to release dynamically allocated memory.
1. If the space pointed to by the parameter arr is not dynamically opened up, the behavior of the free function is undefined.
2. If the parameter arr is a NULL pointer, the function does nothing.
int* arr=(int*)malloc(4);
free(arr);
int a[5]={
0};
char* arr1=(char*)malloc(sizeof(int)*5);
free(arr1);
3.calloc
It is the same as malloc to open up heap memory, except that it will initialize all the opened space to 0;
there are differences between him and malloc's formal parameters, which need to be noted.
void* calloc (size_t num, size_t size);
//开辟num个大小为size字节的空间
1. The function of the function is to open a space for num elements of size size, and initialize each byte of the space to 0.
2. The difference with the function malloc is that calloc initializes each byte of the requested space to all 0s before returning the address
int *arr = calloc(10, sizeof(int));
free(arr);
//不用的时候就一定要free掉内存,虽然我们的代码很短,
//在程序结束自动释放,但是大项目就不一定了。
4.realloc
The emergence of the realloc function makes dynamic memory management more flexible.
He can change the size of the heap space we apply for.
void* realloc (void* ptr, size_t size);
//ptr 是要调整的内存地址
//size 调整之后新大小
//返回值为调整之后的内存起始位置。
int *arr = calloc(10, sizeof(int));
int *p=realloc(arr,20);
free(p);
//将calloc出来的40字节变成了20字节
Note:
There are two situations when realloc changes the size of the space:
1. The starting position of the space remains unchanged (the original space is large enough)
2. The starting position changes
Common mistakes
1. No blank
INT_MAX is a macro definition, which means that we can apply to the operating system for the maximum memory space, which cannot be completed under normal circumstances, so malloc returns NULL, and we dereference a null pointer, which is undefined behavior.
void test(){
int *p = (int *)malloc(INT_MAX);
*p = 10;
free(p);
}
2. Out of bounds
Crossing the boundary is an undefined behavior. Regardless of whether it is dynamically opened or variables in the stack space, they cannot be accessed beyond the boundary.
int* arr=(int *)malloc(sizeof(int)*4);
for(int i=0;i<=4;i++){
*(p+i)=1;
}
3. Non-dynamic development free
free only supports dynamically allocated memory, otherwise an error will be reported
int arr[5]={
0};
free(arr);
4. Not fully released
Incomplete release, causing a memory leak
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
5. Repeat release
This repeated release of memory space is undefined behavior.
int *arr = calloc(10, sizeof(int));
int *p=realloc(arr,20);
free(p);
free(arr);
6. No free space
The memory space created dynamically must be released when not in use.
int* p=(int*)malloc(12);