Table of contents
Why does dynamic memory allocation exist
1. Dereference operation on NULL pointer
2. Out-of-bounds access to dynamically allocated spaces
3. Use free to release non-dynamically allocated memory
4. Use free to release part of a dynamically allocated memory
5. Multiple releases of the same dynamic memory
6. Dynamically open up memory and forget to release it (memory leak)
Advantages of flexible arrays:
learning target:
Why does dynamic memory allocation exist?Introduction to dynamic memory functions:1、malloc;2、free;3、calloc;4、realloc;5. Common dynamic memory errors;6. Memory development;6. Flexible array.
Why does dynamic memory allocation exist
The general way of opening up space has two characteristics:
1. The size of space development is fixed.2. When the array is declared, the length of the array must be specified, and the memory it needs is allocated at compile time
Due to the need for space, it is not just the case above. Sometimes the size of the space we need can only be known when the program is running , and the way of creating space when compiling the array is not enough. At this time, you can only try dynamic storage and development.
Dynamic memory functions:
1. malloc and free
void* malloc (size_t size);size: The size of the memory block in bytes. is an unsigned integer. size_t
1.1 This function applies for a
continuous available
space from the memory and returns a pointer to this space.
1.2 If the allocation is successful , a pointer to the allocated space will be returned .
If the opening fails , a
NULL
pointer
is returned , so the return value of
malloc
must be checked.
1.3 The type of the return value is
void*
, so the
malloc
function does not know the type of the opened space, and the user can decide by himself when using it.
1.4 If the parameter
size
is
0
, the behavior of
malloc
is undefined by the standard and depends on the compiler.
C language provides another function free , which is specially used to release and reclaim dynamic memory . The function prototype is as follows:
void free (void* ptr);ptr: A pointer to a previously allocated block of memory.
1.1 The free
function is used to release the dynamically allocated memory .
1.2 If the space pointed to by the parameter
ptr
is not dynamically opened, the behavior of the
free
function is undefined.
1.3 If the parameter
ptr
is a
NULL
pointer , the function does nothing .
1.4
Both malloc and free are declared in the stdlib.h header file.
#include <stdio.h>
int main()
{
//静态代码
int num = 0;
scanf("%d", &num);
int arr[num] = {0};
//动态代码
int* ptr = NULL;
ptr = (int*)malloc(num*sizeof(int));
//判断ptr指针是否为空
if(NULL != ptr)
{
int i = 0;
for(i=0; i<num; i++)
{
*(ptr+i) = 0;
}
}
//释放ptr所指向的动态内存
free(ptr);
ptr = NULL;
return 0;
}
2. calloc
void* calloc (size_t num, size_t size);num: The number of elements to allocate.size: The size of each element.
2.1 The function of the function is
to open up a space for
num elements of
size size, and
initialize each byte of the space to 0.
2.2
The difference from the function
malloc
is that calloc will initialize each byte of the requested space to all 0s before returning the address .
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)calloc(10, sizeof(int));
if(NULL != p)
{
//使用这块空间
}
free(p);
p = NULL;
return 0;
}
3.realloc
Sometimes we find that the space we applied for in the past is too small, and sometimes we feel that the space we applied for is too large. In order to make the memory reasonable, we must flexible adjustments to the size of the memory . Then the realloc
function can adjust the size of the dynamically allocated memory.
void* realloc (void* ptr, size_t size);ptr: A pointer to a previously allocated block of memory. Or this can be a null pointer , in which case a new block will be allocated (as if called).size: The new size of the memory block in bytes. is an unsigned integer. size_t
3.1 ptr
is the memory address to be adjusted.
3.2
New size after size adjustment.
3.3 The return value is the adjusted memory starting position.
3.4 On the basis of adjusting the size of the original memory space, this function will also move the data in the original memory to the
new
space.
3.5
There are two situations when realloc
adjusts the memory space :
Case 1
: There is enough space after the original space
To expand the memory, directly add space after the original memory, and the data in the original space will not change.
Case 2
: There is not enough space after the original space
When there is not enough space after the original space , the expansion method is: find another continuous space of suitable size on the heap space to use. This function returns a new memory address.
#include <stdio.h>
int main()
{
int *ptr = (int*)malloc(100);
if(ptr != NULL)
{
//业务处理
}
else
{
exit(EXIT_FAILURE);
}
//扩展容量
//ptr = (int*)realloc(ptr, 1000);//这样可以吗?(如果申请失败会如何?)
int*p = NULL;
p = realloc(ptr, 1000);
if(p != NULL)
{
ptr = p;
}
free(ptr);
return 0;
}
Common dynamic memory errors:
1. Dereference operation on NULL pointer
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
2. Out-of-bounds access to dynamically allocated spaces
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;//当i是10的时候越界访问
}
free(p);
}
3. Use free to release non-dynamically allocated memory
void test()
{
int a = 10;
int *p = &a;
free(p);//ok?
}
4. Use free to release part of a dynamically allocated memory
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
}
5. Multiple releases of the same dynamic memory
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放
}
6. Dynamically open up memory and forget to release it (memory leak)
void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
return 0;
}
Program memory allocation:
Several areas of C/C++ program memory allocation:1. Stack area (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 execution ends. The stack memory allocation operation is built into the instruction set of the processor, which is very efficient, but the allocated memory capacity is limited . The stack area mainly stores local variables allocated by running functions , function parameters, return data, return address, etc.2. Heap area (heap): Generally, it is allocated and released by the programmer. If the programmer does not release it , it may be reclaimed by the OS at the end of the program. The allocation method is similar to a linked list.3. Data segment (static area): (static) stores global variables and static data. Released by the system after the program ends .4. Code segment: store the binary code of the function body (class member functions and global functions) .
Flexible array:
typedef struct st_type{int i ;int a []; // flexible array member} type_a ;Some compilers will say that the above definition is wrong, which can be changed to:typedef struct st_type{int i ;int a [ 0 ]; // flexible array member} type_a ;
1.1 A flexible array member in a structure must be preceded by at least one other member.
1.2
The size of this structure returned by sizeof does not include the memory of the flexible array.
1.3 The structure containing flexible array members uses
the malloc ()
function to dynamically allocate memory, and the allocated memory should be larger than the size of the structure to accommodate the expected size of the flexible array.
typedef struct st_type{int i ;int a [ 0 ]; // flexible array member} type_a ;printf ( "%d\n" , sizeof ( type_a )); // The output is 4
Use of flexible arrays:
int i = 0;
//这样柔性数组成员a,相当于获得了100个整型元素的连续空间。
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
//业务处理
p->i = 100;
for(i=0; i<100; i++)
{
p->a[i] = i;
}
free(p);
Advantages of flexible arrays:
The first benefit is:
easy memory release
If our code is in a function for others, you do a secondary memory allocation in it and return the entire structure to the user. The user can release the structure by calling free, but the user does not know that the members of this structure also need to be free, so you can't expect the user to find this out. Therefore, if we allocate the memory of the structure and the memory required by its members at one time, and return a pointer to the structure to the user, the user can release all the memory by doing a free once.
The second advantage is:
this is conducive to access speed .
Continuous memory is beneficial to improve access speed and reduce memory fragmentation (interval memory in the middle of the opened space is not used).
The above is the analysis of personal learning insights and learning, welcome everyone to discuss in the comment area!
Thanks for the one-click three-connection guys! Thanks for the one-click three-connection guys! Thanks for the one-click three-connection guys!