Article directory
foreword
Hello everyone, after a few days, Xiaofan came to share C language learning with you again. Today, I will share with you my understanding of dynamic memory management! ! !
First, why there is dynamic memory allocation
For the space allocated on the stack:
- The space allocation size is fixed.
- When the array is declared, the length of the array must be specified, and the memory it needs is allocated at compile time. But the demand for space is not just the above situation. Sometimes the size of the space we need can only be known when the program is running, so the way to open up space when compiling the array cannot be satisfied
At this time, it is necessary to open up the rectangular dynamic memory in the heap area
2. Introduction of dynamic memory development function
1.malloc
Let’s take a look at the description of him in the library:
Function function: open up a memory block
Parameter size_t: the number of bytes to be applied
Return value: the application fails to return a null pointer, the application returns a pointer to the first address of the application space Header file: stdlib.h Note
: the type of the returned pointer is void* , At this time, you need to convert the pointer to the type you want, which is convenient for access and dereferencing. The space requested by malloc is continuous, but the use of malloc is discontinuous for multiple mallocs
.
int main()
{
int*p=(int*) malloc(40);//申请了40个字节,强制转化为int*类型指针
if (p == NULL)//如果返回空指针的话,申请失败
{
perror("malloc:");//打印错误信息
return 1;//非正常退出
}
for (int i = 0; i < 10; i++)
{
*(p + i) = i;//对每一个四个字节大小的元素赋值,这里*(p+i)的本质就是p[i];
printf("%d", *(p + i));//打印每个元素
}
return 0;//程序正常退出
}
2.calloc
Let’s take a look at the description of it in the library:
Function: Apply for an array in memory, and initialize it to 0;
Parameters: size_t num The number of elements in the application array, size_t size The byte size of each element
Return value: Application failed A null pointer is returned, and the application returns a pointer pointing to the first address of the application space Header file: stdlib.h
Use of calloc function:
int main()
{
int i = 0;
int*p=(int*) calloc(10,sizeof(int));//申请10个元素,每个元素字节大小4
if (p == NULL)//如果返回空指针的话,申请失败
{
perror("calloc:");//打印错误信息
return 1;//非正常退出
}
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p + i));//打印初始化的值
}
free(p);
p = NULL;
return 0;
}
The difference between malloc and calloc:
the difference from the function malloc is that calloc will initialize each byte of the requested space to all 0s before returning the address
3.realloc
Let’s take a look at the description of it in the library:
Function: Memory block expansion
Parameters: The first parameter receives the first address of the memory block to be expanded, and the total byte size after expansion (including the original byte size)
Header file: stdlib .h
The initial expansion space is empty, then the usage of realloc and malloc is exactly the same
Return value: the first address of the expanded space
Usage of realloc function:
int main()
{
int* p = (int*)malloc(40);//申请了40个字节,强制转化为int*类型指针
if (p == NULL)//如果返回空指针的话,申请失败
{
perror("malloc:");//打印错误信息
return 1;//非正常退出
}
for (int i = 0; i < 10; i++)//循环打印扩容前的元素
{
*(p + i) = i;
printf("%d ", *(p + i));
}
int* ptr = (int*)realloc(p, 80);//原空间够用ptr==p,不够用的话ptr存放新地址
if (ptr != NULL)//扩容成功
{
p = ptr;//原空间够用ptr==p,不够用的话ptr存放新地址,重新将新地址给p
}
for (int i = 10; i < 20; i++)//扩容后新空间的
{
*(p + i) = i;
printf("%d ", *(p + i));
}
free(p);
p = NULL;
return 0;
}
4.free
Let’s take a look at the description of it in the library:
Function: Release the memory block
Parameter: Pointer to receive the first address of the memory block to be released
Header file: stdlib.h
Return value: None
Note:
When the requested space pointed to by p is released, the p pointer points to a random location, and p becomes a wild pointer, so we need to set it to empty after release! ! !
If we do not release the memory requested by the dynamic memory, the program ends, and the dynamically requested memory is automatically reclaimed by the operating system. If the free function is not used to release the requested space, it will remain in the heap until the end of the program, causing memory leaks
3. Common errors in dynamic memory development
1. Dereferencing NULL by mistake
for example:
int main()
{
int* p = (int*)malloc(1000);
int i = 0;
if (p ==NULL)
{
return 1;
}
for (i = 0; i < 250; i++)
{
*(p + i) = i;
}
free(p);
p = NULL;
return 0;
}
When allocating memory fails, it will return empty, which is easy to cause this error.
Solution: Make a judgment after opening up the memory, such as the if judgment in the above code
2. An out-of-bounds access is made to the dynamically opened space
int main()
{
int* p = (int*)malloc(100);
int i = 0;
if (p ==NULL)
{
return 1;
}
for (i = 0; i <=25; i++)//越界访问
{
*(p + i) = i;
}
free(p);
p = NULL;
return 0;
}
Solution: Manually check whether it is out of bounds
3. The free operation is performed on the non-dynamically allocated memory
int main()
{
int a = 10;
int* p = &a;
free(p);
p = NULL;
return 0;
}
4. Only free part of the dynamically allocated memory
int main()
{
int* p = (int*)malloc(100);
if (p == NULL)
{
return 1;}
int i = 0;
for (i = 0; i < 10; i++)
{
*p = i;
p++;
}
free(p);
p = NULL;
return 0;
}
Solution:
Do not change the pointer variable that saves the first address of the dynamically opened space, you can use the method of intermediate variables when using it! ! !
For example:
int main()
{
int* p = (int*)malloc(100);
if (p == NULL)
{
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*(p+i)= i;
printf("%d ", *(p + i));
}
free(p);
p = NULL;
return 0;
}
5. Free the space memory that has been released multiple times
int main()
{
int* p = malloc(40);
if (p == NULL)
{
return 1;
}
free(p);
free(p);
p = NULL;
return 0;
}
Four. Summary
This time the content is shared here. If you think it is helpful to you, please give it a thumbs up. If there is something wrong with the sharing, please correct me. Thank you for reading! ! !