当前位置:网站首页>C dynamic memory management details
C dynamic memory management details
2022-07-24 03:12:00 【Langyu 123】
Catalog
Why is there dynamic memory allocation
Dynamic memory allocation function
Causes of memory fragmentation
Definition and characteristics of flexible array
Use and advantages of flexible arrays
Common errors in using dynamic memory functions
Why is there dynamic memory allocation
Generally, when we store the data needed for program operation , Will select an array to store , But the size of the array cannot be changed , Set as many as you want . The operation of the program is dynamic , We often don't know how much space is needed to store the generated data , If the space given by array is too large , It will cause a great waste of memory space , The operation efficiency is also reduced , Giving too little is not enough , Cause the program to crash . So we need a dynamic memory allocation mechanism , If insufficient memory is detected , Will automatically open up new memory space , For storing data .
Dynamic memory allocation function
stay C In language , Memory allocation functions have 3 individual , Namely malloc() , calloc(), realloc()
Remember when using dynamic memory functions , Remember to introduce the header file <stdlib.h>( Countless lessons of blood and tears )
And after the allocated memory is no longer used , Remember to use free() To release , Otherwise, it will cause memory leakage .
Memory leaks will be explained later , Next, let's introduce this 3 Memory development function
malloc
void* malloc (size_t size)
This function applies to memory for a contiguous block of free space , And return the pointer to this space .
If the memory development fails, a null pointer is returned , Therefore, when opening up space, you need to check the returned pointer
// use malloc open up 10 individual int Integer space
int main()
{
int* p = (int*)malloc(sizeof(int) * 10);
if (NULL == p)
{
printf("fail\n");
return 1;
}
free(p);
p = NULL;
return 0;
}
// Normal development process calloc
void* calloc (size_t num, size_t size);
calloc And malloc The difference in function is calloc It can initialize the opened space to 0, If you need to initialize the opened space , You can choose calloc, In addition, there are slight differences in parameters ,calloc To pass two parameters , One parameter is the number of spaces of a certain type , The other is the type of space to be developed . In fact, it means malloc Disassemble the parameters of , above malloc( sizeof(int) *10 ) become calloc by calloc( 10, sizeof(int) )
realloc
The first two functions may give you some doubts , It doesn't feel very different from the space opened up by using arrays , It does not reflect dynamic development , that realloc Can solve these problems , Let's see realloc Statement of
void* realloc (void* ptr, size_t size)
According to the statement , The first parameter is a pointer , The second parameter is an unsigned integer number , What do they mean . The first parameter needs to pass a pointer to the space we have opened up before , In the previous example , We try to use malloc Opens the 10 An integer space , And use pointer variables p To maintain this space , Assume that this 10 Integer space is not enough , I also want to expand 10 An integer space , And save the data generated before , This is the time realloc Function plays a great role . We maintain the pointer of opening up space before p Transfer the past , Then the second parameter is the size of the reopened space , We want to expand 10 A capacity , Plus the previous one 20 Space , then realloc Will return a pointer , The returned pointer can be divided into three cases1. Space development failed , Returns a null pointer
2. The unused space behind the original space can meet the needs of expansion , Then return to the pointer that maintains the original space
3. The unused space behind the original space does not meet the needs of expansion , Looking for a new space , Returns the starting address of the new space
Let's take a closer look at
int main()
{
int* p = (int*)malloc(sizeof(int) * 10);
if (NULL == p)
{
printf("fail\n");
return 1;
}
// ......
......
// After a period of program use , It is found that the space originally opened up is not enough , To amplify 10 individual
int *ps = (int*)realloc( p, sizeof(int)*20 )
if( NULL == ps)
{
printf("fail\n");
return 1;
}
p = ps; // If you still want the previous pointer p To maintain this new space , You can do this
ps = NULL;
//.......
free(p);
p = NULL;
return 0;
}
The cause of the memory leak
Once many programs run , In addition to equipment shutdown , Basically, it has been running , If we malloc A lot of space , And it is useless after use free() To release , because c/c++ There is no automatic recycling mechanism , This leads us to malloc This space of has been occupied in memory , After not using , The program will no longer care about maintaining the pointer of this space , It is likely to cause the loss of the pointer to the maintenance space , Thus losing control of this space , During program operation , I can't find this space anymore , I can't use this space anymore , That is, memory leakage .
And we usually write small programs , The program closes after running for a while , At this time, all the space occupied by the program is returned to the operating system , But we should form the good habit of releasing as we use it , Otherwise, contact with large projects in the future , Memory leaks are dangerous .
Causes of memory fragmentation
When we use dynamic memory functions to open up space , The heap area of memory is used , If we use it frequently malloc
realloc To open up memory space , It will divide the stacking area into pieces , Every two pieces of space opened up may be mixed with some unused space , And these spaces are very fragmented and difficult to be used again , It will reduce the utilization of memory .
Flexible array
Definition and characteristics of 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
characteristic :1. A flexible array member in a structure must be preceded by at least one other member .
2.sizeof The size of the structure returned does not include the memory of the flexible array .
3. Structures that contain flexible array members use malloc () Function to dynamically allocate memory , And the allocated memory should This is larger than the size of the structure , To fit the expected size of the flexible array
typedef struct stu
{
int age;
char name[];
}S;
//char name[] Is a flexible array , Its size can be undefined 
Use and advantages of flexible arrays
// The use of flexible arrays
struct S
{
int n;
int arr[];
};
int main()
{
structu S s;
// Such creation will cause the flexible array to have no space
struct S* ps= (struct S*)malloc(sizeof(struct S) + 40);
//40 Is for flexible arrays arr Reserved size
}
struct S
{
int n;
int *arr;
};
int main()
{
struct S* ps = (struct S*)malloc( sizeof(struct S) );
ps->arr = (int*)malloc(40);
}
// This is the use of ordinary structures Advantages of flexible arrays over ordinary structures
1. Compare with flexible array , The above common structure will consume more memory , We should also open up and release twice
2. Because ordinary structures need malloc two , Will cause memory fragmentation , Resulting in reduced memory utilization , The running speed is slightly reduced
Common errors in using dynamic memory functions
1. Yes NULL Pointer to dereference
The main reason for this is that the pointer returned by the memory development function is not checked , If you don't check , And the development just failed , This causes a reference to null pointers
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;// If p The value of is NULL, There will be problems
free(p);
}2. Cross border visit to the opened space
This situation is the improper use of space , Only opened up 10 Block space , Wrong access to the eleventh space
3. Use of non dynamically opened memory space free() To free up space
free() It can only be used to release the space opened up dynamically
void test()
{
int a =0;
int *p = &a;
free(p);
}
// This is wrong 4. Multiple releases of the same dynamic memory
A piece of dynamic development memory is released once , Releasing multiple times is wrong
5. Use free When released, only part of it is released
Many times we have opened up a space dynamically , With a pointer p To maintain the ,p Point to the starting address of this space , But when using this space , May lead to p No longer point to the starting position , Are you putting p When you return to the starting position, put p Release , This is wrong .
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p No longer points to the start of dynamic memory
}6. Forget to release the opened memory ( Memory leak )
Many students may say that they have already remembered to release the opened memory , Will not cause memory leaks , In fact, our logic is not as rigorous as we think , Take a look at the following program
int test()
{
int* p = (int*)malloc(sizeof(int) * 2);
if (NULL == p)
{
printf("fail\n");
return -1;
}
scanf("%d %d", p, p + 1);
if ( *p > *(p+1) )
{
printf(" The larger number is :");
return *p;
}
else
{
printf(" The larger number is :");
return *(p+1);
}
free(p);
p = NULL;
}
int main()
{
int m = test();
printf("%d", m);
return 0;
}The above is a simple program to return a larger value , If you feel there is nothing wrong with this program , So I'm very sorry , You have caused a memory leak , Let's analyze the reasons first , We are test Two... Are opened in the function int Type of space , And enter two values for comparison , So far, there is nothing wrong , The problem is that we return a return value after comparison , Just left test() function , We were not right before we left p Conduct free Release , and p Again test Internally defined , It can only be in test For internal use , Leave test,p It gives back the memory , Turned into a wild pointer , That is to say, we will never pass p To find this unreleased space , During program operation , This space was leaked
Does it feel that memory leakage is not so simple , If you see the problem at a glance , Then you have strong insight and logic , Very clever , Keep this vigilance , If you don't see , So now you have been planted with this vigilance
Pay more attention to observation in the future , Don't be blindly confident .
边栏推荐
- C. Minimum Ties-Educational Codeforces Round 104 (Rated for Div. 2)
- How to write selenium's testng.xml
- Gpushare.com | 如何使用TensorBoardX可视化工具?
- FTP服务与配置
- The process of solving a bug at work
- [hdlbits questions] Verilog language (2) vectors
- How to realize software function safety
- TCP connection principle
- 198. House raiding
- JS small game running bear and cat source code
猜你喜欢
![[MySQL learning] install and use multiple versions of MySQL, MySQL 8 and MySQL 5.7 at the same time, compressed version](/img/08/3765b34809cc4c723608f5d2e86ed4.png)
[MySQL learning] install and use multiple versions of MySQL, MySQL 8 and MySQL 5.7 at the same time, compressed version

String.split()最详细源码解读及注意事项
[email protected] Principle of use"/>(6) Decorator extension [email protected] Principle of use

198. House raiding

A simple and perfect WPF management system framework source code

The new idea 2022.2 was officially released, and the new features are nice

JIRA automation experience sharing for 2 years

Xiaodi and Xiaohui

PMP preparation experience | good habits, good process, good results

Ways to improve the utilization of openeuler resources 01: Introduction
随机推荐
AcWing 4498. 指针 (DFS)
FTP服務與配置
The new idea 2022.2 was officially released, and the new features are nice
Babylon.js cool canvas background animation JS special effects
go IO操作-文件写
Detailed explanation of wechat official account online customer service access methods and functions
Soft test --- fundamentals of programming language (Part 1)
Binary tree traversal
kettle
Liveqing live RTMP on demand video streaming platform how to carry the Sid and token returned by the login interface to call authentication streamtoken video streaming authentication
LCD1602 - binge 51
CMT 注册——Google Scholar Id,Semantic Scholar Id,和 DBLP Id
JS 数组 isAarray() typeof
How will you answer the "Hello world" challenge written in C language?
Huawei then responded to the rumor of "cleaning up employees over the age of 34". How can programmers cope with the "35 year old crisis"?
Acwing 4499. draw a circle (similar to a triangle)
Basic knowledge of trigger (Part 2)
In the future, when the interviewer asks why you don't recommend using select *, please answer him loudly!
【HDLBits 刷题】Verilog Language(2)Vectors 部分
SolidWorks cannot reference references