dynamic memory management
dynamic memory function
malloc
void* malloc (size_t size)
This function applies for a contiguous available space from memory and returns a pointer to this space.
int main() {
int arr[10] = {
0 };
//动态内存管理
int* p = (int*)malloc(40);
if (p == NULL) {
printf("%s\n", strerror(errno));
return 1;
}
//使用
int i = 0;
for (i = 0; i < 10; i++) {
*(p + i) = i;
}
for (i = 0; i < 10; i++) {
printf("%d ", *(p + i));
}
return 0;
}
If the allocation is successful, a pointer to the allocated space is returned.
If the opening fails, a NULL pointer is returned, so the return value of malloc must be checked.
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
.
If the parameter size is 0, the behavior of malloc is undefined by the standard and depends on the compiler.
free
void free (void* ptr);
C language provides another function free, which is specially used to release and recycle dynamic memory.
int main() {
int arr[10] = {
0 };
//动态内存管理
int* p = (int*)malloc(40);
if (p == NULL) {
printf("%s\n", strerror(errno));
return 1;
}
//使用
int i = 0;
for (i = 0; i < 10; i++) {
*(p + i) = i;
}
for (i = 0; i < 10; i++) {
printf("%d ", *(p + i));
}
//没有free
//并不是说内存空间就不会收了
//当程序退出的时候,系统会自动回收内存空间
free(p);
p = NULL;
return 0;
}
If the space pointed to by the parameter ptr is not dynamically opened, the behavior of the free function is undefined.
If the parameter ptr is a NULL pointer, the function does nothing.
calloc
void* calloc (size_t num, size_t size);
The calloc function is also used for dynamic memory allocation
//开辟10个整型的空间
int main(){
int* p = (int*)calloc(10, sizeof(int));
if (p == NULL) {
printf("%s\n", strerror(errno));
return 1;
}
//打印
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d", *(p + i));
}
//释放
free(p);
p = NULL;
return 0;
}
The function of the function is to open up a space for num elements whose size is size, and initialize each byte of the space to 0.
The only difference from the function malloc is that calloc will initialize each byte of the requested space to all 0s before returning the address
realloc
void realloc (void ptr, size_t size);**
The emergence of the realloc function makes dynamic memory management more flexible.
Sometimes we find that the space we applied for in the past is too small, and sometimes we feel that the space we apply for is too large. In order to make the memory reasonable, we must make flexible adjustments to the size of the memory. Then the realloc function can adjust the size of the dynamically allocated memory
.
int main()
{
int* p = (int*)malloc(40);
if (p == NULL) {
printf("%s\n", strerror(errno));
return 1;
}
//使用
//1,2,3,4,5,6,7,8,9,10
int i = 0;
for (i = 0; i < 10; i++) {
*(p + i) = i + 1;
}
//扩容
//p = realloc(p, 80);
//可能扩容失败
int* ptr = realloc(p, 80);
if (ptr != NULL) {
p = ptr;
}
//使用
for (i = 0; i < 10; i++) {
printf("%d", *(p + i));
}
free(p);
p = NULL;
return 0;
}
int main()
{
int* p = (int*)malloc(40);
if (p == NULL) {
printf("%s\n", strerror(errno));
return 1;
}
//使用
//1,2,3,4,5,6,7,8,9,10
int i = 0;
for (i = 0; i < 10; i++) {
*(p + i) = i + 1;
}
//扩容
//p = realloc(p, 80);
//可能扩容失败
int* ptr = realloc(p, 8000);
if (ptr != NULL) {
p = ptr;
}
//使用
for (i = 0; i < 10; i++) {
printf("%d", *(p + i));
}
free(p);
p = NULL;
return 0;
}
ptr is the memory address
size to be adjusted, the new size after adjustment,
and the return value is the starting position of the memory after adjustment.
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.
There are two situations when realloc adjusts the memory space:
Case 1: There is enough space after the original space
Case 2: There is not enough space after the original space
Common Dynamic Memory Mistakes
Dereference operations on NULL pointers
int main()
{
int* p = (int*)malloc(40);
if (p == NULL) {
return 1;
}
*p = 20;
free(p);
p = NULL;
return 0;
}
Out-of-bounds access to dynamically allocated space
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
int i = 0;
for (i = 0; i < 10; i++) {
p[i] = i;
printf("%d ", p[i]);
}
free(p);
p = NULL;
return 0;
}
Use the free function for non-dynamically allocated memory
int main() {
int a = 10;
int* p = &a;
free(p);
p = NULL;
return 0;
}
Use free to release part of a dynamically allocated memory
int main() {
int* p = (int*)malloc(40);
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
int i = 0;
for (i = 0; i < 10; i++) {
*p = i;
p++;
}
free(p);
p = NULL;
return 0;
}
Multiple releases of the same dynamic memory
int main() {
int* p = (int*)malloc(40);
free(p);
p = NULL;
free(p);
}
Dynamically open up memory and forget to release it (memory leak)
Open up memory and do not release it
void test() {
int* p = (int*)malloc(40);
int flag = 0;
scanf("%d", &flag);
if (flag == 5)
return 0;
free(p);
p = NULL;
}
int main() {
test();
return 0;
}
The problem of returning the address of the stack space
int* test() {
int a = 10;
int* p = &a;
return p;
}
int main() {
int* p = test();
printf("hehe\n");
printf("%d", *p);
}
Memory allocation of C/C++ program
flexible array
In C99, the last element in a structure is allowed to be an array of unknown size, which is called a "flexible array" member.
typedef struct st_type
{
int i;
int a[0];//柔性数组成员
}type_a;
features
- A flexible array member in a structure must be preceded by at least one other member.
- The size of such a structure returned by sizeof does not include memory for flexible arrays.
- Structures containing flexible array members use the malloc() function for dynamic allocation of memory, and the allocated memory should be larger than the size of the structure
to accommodate the expected size of the flexible array.
struct s {
int a;
int arr[];
};
int main() {
printf("%d", sizeof(struct s));
return 0;
}
struct s {
int a;
int arr[];
};
int main() {
//柔性数组的使用
struct s* ps = (struct s*)malloc(sizeof(struct s) + 40);
return 0;
}