Chapter 9: Advanced Dynamic Memory Management in C Language

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

insert image description here

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

  1. A flexible array member in a structure must be preceded by at least one other member.
  2. The size of such a structure returned by sizeof does not include memory for flexible arrays.
  3. 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;
}

Guess you like

Origin blog.csdn.net/yanyongfu523/article/details/128791346