1. Why is there dynamic memory allocation
* Dynamic memory is opened up in the heap *
The way we have mastered to open up memory is to directly define variables by type , The developed memory is fixed , image :
int a=20; // Open up four bytes in stack space
And arrays , We can specify the size of the open space , image :
char arr[10] = {0}; /// Open up in stack space 10 Contiguous space of bytes
But when the program is running , Many times, we will encounter the problem of waste caused by insufficient memory or too much memory , So is there a way to use how much memory and open up how much memory ? This is the dynamic memory to be introduced in this article .
2. Introduction to dynamic memory function
2.1 malloc and free
malloc and free All declared in stdlib.h In header file
void* malloc (size_t size); // Apply for a continuously available space from memory , And return a pointer to this space
If the development is successful , Returns a pointer to the opened space . If the development fails , Returns a NULL Pointer . The type of return value is void*
,malloc Function does not know the type of open space , It's up to you to decide when you use it .
void free (void* ptr); //free Function is used to free dynamic memory
If parameter ptr The space pointed to is not opened up dynamically , that free The behavior of the function is undefined .
If parameter ptr yes NULL Pointer , Then the function does nothing .
give an example :
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h>
int main() { // open up 10 An integer space int* p = (int*)malloc(40); if (NULL==p) {
printf("%s\n",strerror(errno)); // Judge the cause of development failure return 0; } // use // release free(p);
// Return space to the system , But the content has not changed , You can also pass p To find the address p = NULL; // So set the address to a null pointer return 0; }
2.2 calloc
void* calloc (size_t num, size_t size); //num Is the number of elements ,size Is the size of each element
notes : And function malloc The only difference is calloc Each byte of the requested space will be initialized to full before returning the address 0
When used calloc To open up 10 When an integer space
int* p = (int*)calloc(10,sizeof(int));
2.3 realloc
void* realloc (void* ptr, size_t size); //ptr Is the memory address to be adjusted size New size after adjustment
// The return value is the adjusted starting position of memory
realloc There are two situations when adjusting memory space :
1. When there is enough space behind the original address , You can continue to open up space at the original address , Last return to the starting address .
2. When the space behind the original address is not enough to open up the space we need , that realloc Will automatically find a space enough to store what we need , And copy the contents of the original address to the new space , Release the contents of the original address , Returns the initial address of the opened space .
We can first judge whether the development is successful , Then assign the address to p
3. Common dynamic memory errors
3.1 yes NULL Dereference operation of pointer
When opening up dynamic memory , Be sure to judge the function that returns null pointer , Prevent dereference of null pointers , To avoid program problems .
3.2 Cross border access to dynamic open space
int *p = (int *)malloc(10*sizeof(int)); // Open up memory if(NULL == p) // Judge whether the development is successful {
exit(EXIT_FAILURE); } int i=0; for(i=0; i<=10; i++) { *(p+i) = i;// When i yes 10 Cross border visits when
} free(p);
This can be understood as an array , Cannot access subscript 10 Address of , Will result in cross-border visits .
3.3 Use of non dynamic memory free release
void test() { int a = 10; int *p = &a; free(p); } int main() { test(); return
0; }
It is not a space opened up by dynamic memory. The memory is not in the heap , It's not necessary free release , The space opened in the stack area will be returned to the system automatically after the scope is out , Not necessary , It is also not allowed to use free Release .
3.4 use free Freeing a piece of dynamic memory
void test() { int *p = (int *)malloc(100); p++; free(p);//p No longer point to the starting position of dynamic memory }
Freeing some memory is not supported , This way of writing does not support and is not desirable . It can only be released from the starting position of dynamic memory .
3.5 Multiple releases of the same dynamic memory
void test() { int *p = (int *)malloc(100); free(p); free(p);// Repeated release }
Repeated release will also report an error
When p After the first release , take p=NULL, If you release it again, there will be no problem ; Write code to avoid repeated releases , At the same time, remember to set the address as a null pointer after each release .
If you forget to release the open space , It will cause the problem of memory leakage ( You lose control of this segment of memory before releasing it , This causes a waste of memory )
Technology