当前位置:网站首页>Dynamic memory management
Dynamic memory management
2022-07-04 20:17:00 【Hundred words lingdu】
Dynamic memory management
One 、 Why is there dynamic memory allocation
This is the memory development we master :
int arr[10]={
0};// Open up on the stack 40 Byte space
int num=0;// Open up on the stack 4 Byte space
But there are two characteristics of the way to open up space :
1. The size of the space opening is fixed .
2. Arrays are declared , You must specify the length of the array , The memory it needs is allocated at compile time .
But the need for space , It's not just that . Sometimes the amount of space we need is known when the program is running ,
The way to open up space when compiling arrays is not enough .
At this time, you need to dynamically open up memory .
Two 、 Introduction to dynamic memory functions
Add : What is the wild pointer ?
“ Wild pointer ” It means that the value in the pointer variable is an illegal memory address , but “ Wild pointer ” It's not a null pointer (NULL),“ Wild pointer ” The memory pointed to is not available ,“ Wild pointer ” It often leads to ” Memory out of bounds 、 Segment error “ Other questions
2.1 malloc( Will not initialize )
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
// Open up ten integer
int* arr = (int*)malloc(sizeof(int) * 10);
if (NULL == arr)
{
printf("%s\n", strerror(errno));
return 0;
}
// Use
int i = 0;
for (i = 0; i < 10; i++)
{
*(arr + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
// Release
free(arr);//free Can only release malloc,realloc,calloc Open up space
arr = NULL;// When released ,arr Became a wild pointer , So we need to take arr Into a NULL
return 0;
}
2.2 calloc( Will be initialized to 0)
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
// Open up ten integer
int* arr = (int*)calloc(10, sizeof(int));
if (NULL == arr)
{
printf("%s\n", strerror(errno));
return 0;
}
// Use
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);// Print 10 individual 0
}
// Release
free(arr);//free Can only release malloc,realloc,calloc Open up or adjust space
arr = NULL;// When released ,arr Became a wild pointer , So we need to take arr Into a NULL
return 0;
}
2.3 realloc( Will not initialize )
2.3.1 characteristic
1、 Can open up space // When realloc The first parameter of is NULL when ,realloc Open up space
//int*arr=(int*)realloc(NULL,40);
2、 Space can be adjusted ( Two cases )// When realloc The first parameter of is not NULL when ,realloc Adjust the space
//int*ptr=(int*)realloc(p,80);
give an example
2.3.2 Open up space
//1 Open up space
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
// Open up ten integer
int* arr = (int*)realloc(NULL, sizeof(int) * 10);
if (NULL == arr)
{
printf("%s\n", strerror(errno));
return 0;
}
// Use
int i = 0;
for (i = 0; i < 10; i++)
{
*(arr + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
// Release
free(arr);//free Can only release malloc,realloc,calloc Open up or adjust space
arr = NULL;// When released ,arr Became a wild pointer , So we need to take arr Into a NULL
return 0;
}
2.3.3 Adjust the space
//2 Adjust the space
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
// Open up ten integer
int* arr = (int*)calloc(10, sizeof(int));
if (NULL == arr)
{
printf("%s\n", strerror(errno));
return 0;
}
// Use
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", *(arr+i));
}
// Need to increase capacity 80
int* ptr = (int*)realloc(arr, sizeof(int) * 20);
// If the adjustment fails , prevent NULL Assign to arr
if (NULL != ptr)
{
arr = ptr;
ptr = NULL;
}
// Continue to use
for (i = 10; i < 20; i++)
{
*(arr + i) = i;
}
for (i = 10; i < 20; i++)
{
printf("%d ", *(arr+i));
}
// Release
free(arr);//free Can only release malloc,realloc,calloc Open up or adjust space
arr = NULL;// When released ,arr Became a wild pointer , So we need to take arr Into a NULL
return 0;
}
realloc
There are two situations when adjusting space
1、
Case one , When we use realloc
When adjusting space , If there is enough space behind the original dynamic space , Then it will continue to expand space . Return the address pointing to the starting position of the original opening space .
2、
The second case , When we use realloc
When adjusting space , If the space originally opened dynamically is not expanded enough in the subsequent space , Then you will find enough space , And copy the contents of the original dynamic space , Return the address pointing to the starting position of the post opening space .
3、 ... and 、 Common dynamic memory errors
3.1 Yes NULL Dereference operation of pointer
#include<limits.h>//INT_MAX Required header file
#include<stdlib.h>
int main()
{
int*p=(int*)malloc(INT_MAX);// Open up failure return NULL
if(p==NULL)
return 0;
int i=0;
for(i=0;i<10;i++)
{
*(p+i)=i;
}
return 0;
}
3.2 Space for dynamic memory
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
int main()
{
char*p=(char*)malloc(10*sizeof(char));
if(p==NULL)
{
printf("%s\n",strerror(errno));
}
// Use
int i=0;
for(i=0;i<=10;i++)
{
*(p+i)=i;
}
free(p);
p=NULL;
return 0;
}
3.3 Free space for non dynamic memory
int main()
{
int a=10;
int*p=&a;
free(p);// error ,free Can only release malloc,realloc,calloc Open up or adjust space
p=NULL;
return 0;
}
notes : The stack in the data structure cannot be equated with the stack area in the memory
3.4 Use free Release a piece of dynamic memory
int main()
{
int*p=(int*)malloc(sizeof(int)*10);
if(p==NULL)
{
printf("%s\n",strerror(errno));
return 0;
}
// Use
int i=0;
for(i=0;i<5;i++)
{
*P=i+1;
p++;
}
// Release
free(p);//p Does not point to the starting position of dynamic memory
p=NULL;
return 0;
}
3.5 Multiple releases of the same block of memory
int main()
{
int*p=(int*)malloc(sizeof(int)*10);
if(p==NULL)
{
printf("%s\n",strerror(errno));
return 0;
}
// Use
int i=0;
for(i=0;i<5;i++)
{
*(P+i)=i+1;
}
// Release
free(p);
free(p);// error , Release many times ; If after the first release , take p Set to null pointer , Can be released again
return 0;
}
3.6 Dynamic memory forget to release ( Memory leak )
void test()// Forgetting to release the dynamically opened space that is no longer used will cause memory leakage
{
int*p=(int*)malloc(100);
if(NULL!=p)
{
*p=20;
}
}
int main()
{
test();
while(1);
}
Four 、 Several classic written test questions
function Test What is the result of the function ?
Example 1
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
Test();
return 0;
}
answer : Program error
1、strcpy
The first argument to the function is a null pointer ( because GetMemory
When a function passes parameters, it passes the value of the pointer , therefore ,str
The content of will not change )
2、 After dynamically opening up memory , There is no release , Memory leaks can result
Example 2( Return stack space address problem )
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
int main()
{
Test();
return 0;
}
answer : Program error
1、 stay GetMemory
When the function is finished ,p Variables will be destroyed , Assign the address of destruction to str
, Re print , Will form illegal access
Example 3
void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
int main()
{
Test();
return 0;
}
answer : Print hello
1、 The space opened up by dynamic memory is not released , Memory leaks can result
Example 4
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
int main()
{
Test();
return 0;
}
answer :
1、 stay free(str)
after , Didn't put str
Set as NULL
1、 stay str
After the space pointed to is released , You can't use , It will cause illegal access to memory .
5、 ... and 、C/C++ Program memory development
C/C++ Several areas of program memory allocation :
1、 The stack area (stack): When executing a function , The memory units of local variables in the function can be created on the stack , At the end of the function, these storage units are automatically released . Stack memory allocation operations are built into the processor's instruction set , It's very efficient , But the allocated memory capacity is limited . The stack area mainly stores the local variables allocated by running functions 、 Function parameter 、 Return the data 、 Return address, etc .
2、 Heap area (heap): Release is usually assigned by the programmer , If programmers don't release , At the end of the program, the OS Recycling . The distribution is similar to a linked list .
3、 Data segment ( Static zone ): Store global variables 、 Static data . Released by the system at the end of the program .
4、 Code segment : Store function body ( Class member functions and global functions ) The binary code of .
6、 ... and 、 Flexible array
C99 in , The last element in the structure is allowed to be an array of unknown size , This is called 『 Flexible array 』 member .
for example :
//1
struct s1
{
int n;
int arr[0];// The size is unspecified
};
//2 For some compilers, the first writing method will report an error and cannot be compiled. You can use the second writing method
struct s2
{
int n;
int arr[];
};
6.1 The characteristics of flexible arrays
• A flexible array member in a structure must be preceded by at least one other member .
•sizeof
The size of the structure returned does not include the memory of the flexible array .
• Structures that contain flexible array members usemalloc ()
Function to dynamically allocate memory , And the allocated memory should be larger than the size of the structure , To fit the expected size of the flexible array
typedef struct st_type
{
int i;
int a[0];// Flexible array members
}type_a;
printf("%d\n", sizeof(type_a));// The output is 4
6.2 The use of flexible arrays
// Code 1
int i = 0;
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
// Use
p->i = 100;
for(i=0; i<100; i++)
{
p->a[i] = i;
}
free(p);
So flexible array members a, It's equivalent to getting 100 A continuous space of integer elements .
6.3 The advantages of flexible arrays
Aforementioned type_a The structure can also be designed as :
// Code 2
typedef struct st_type
{
int i;
int *p_a;
}type_a;
type_a *p = (type_a *)malloc(sizeof(type_a));
p->i = 100;
p->p_a = (int *)malloc(p->i*sizeof(int));
// Use
for(i=0; i<100; i++)
{
p->p_a[i] = i;
}
// Release space
free(p->p_a);
p->p_a = NULL;
free(p);
p = NULL;
The code above 1 And code 2 The effect is the same , What's the difference? ? Which is better ?
Code 1:
Code 1 Opening up space in memory , Pictured above
In the code 1 The situation of ,malloc
once type_a
Type structure is enough .
Code 2:
Code 2 Opening up space in memory , Pictured above
Code 2 If you want to achieve the effect of code one , It needs to be done first malloc
type_a
Type of structure , Again malloc
A continuous space , This needs to be done twice malloc
, It also needs to be done twice free, At the same time, it will also produce memory fragments .
summary :
Above Code 1 and Code 2 It can do the same thing , however Method 1 There are two benefits to the implementation of :
The first advantage is : Convenient memory release
If our code is in a function for others , You do a secondary memory allocation in it , And return the whole structure to the user . The user calls free You can release the structure , But the user doesn't know that the members in the structure also need free, So you can't expect users to find out . therefore , If we allocate the memory of the structure and its members at one time , And return a structure pointer to the user , The user does it once free You can also free up all the memory .
The second advantage is : This is good for access speed .
Continuous memory is good for improving access speed , It also helps reduce memory fragmentation .
边栏推荐
- 凌云出海记 | 一零跃动&华为云:共助非洲普惠金融服务
- Pointnext: review pointnet through improved model training and scaling strategies++
- 双冒号作用运算符以及命名空间详解
- 92.(cesium篇)cesium楼栋分层
- HDU 1097 A hard puzzle
- Data set division
- Kotlin cycle control
- Application practice | Shuhai supply chain construction of data center based on Apache Doris
- 原来这才是 BGP 协议
- @Data source connection pool exhaustion caused by transactional abuse
猜你喜欢
黑马程序员-软件测试--08阶段2-linux和数据库-23-30-进程端口相关,修改文件权限,端口号信息的获取,程序和进程相关操作,linux命令案例
Euler function
TCP两次挥手,你见过吗?那四次握手呢?
应用实践 | 蜀海供应链基于 Apache Doris 的数据中台建设
Niuke Xiaobai month race 7 who is the divine Archer
原来这才是 BGP 协议
What is the application technology of neural network and Internet of things
Cbcgpprogressdlg progress bar used by BCG
Installation and use of VMware Tools and open VM tools: solve the problems of incomplete screen and unable to transfer files of virtual machines
Employment prospects and current situation of Internet of things application technology
随机推荐
Kotlin cycle control
kotlin 继承
Thinking on demand development
西门子HMI下载时提示缺少面板映像解决方案
B2B mall system development of electronic components: an example of enabling enterprises to build standardized purchase, sale and inventory processes
Double colon function operator and namespace explanation
为什么最大速度是光速
Dark horse programmer - software testing - stage 07 2-linux and database -09-24-linux command learning steps, wildcards, absolute paths, relative paths, common commands for files and directories, file
Delete the characters with the least number of occurrences in the string [JS, map sorting, regular]
The company needs to be monitored. How do ZABBIX and Prometheus choose? That's the right choice!
What financial products can you buy with a deposit of 100000 yuan?
On communication bus arbitration mechanism and network flow control from the perspective of real-time application
kotlin 基本使用
English grammar_ Noun - use
水晶光电:长安深蓝SL03的AR-HUD产品由公司供应
Application practice | Shuhai supply chain construction of data center based on Apache Doris
BCG 使用之CBCGPProgressDlg进度条使用
ACM组合计数入门
Find the nth power of 2
黑马程序员-软件测试--07阶段2-linux和数据库-09-24-linux命令学习步骤,通配符,绝对路径,相对路径,文件和目录常用命令,文件内容相关操作,查看日志文件,ping命令使用,