C Language - Dynamic Memory Allocation (12.1)

Table of contents

mind Mapping:

1. Why does dynamic memory allocation exist

2. Introduction to dynamic memory functions

2.1 malloc

2.2 free

2.3 calloc

2.4 realloc

3. Common dynamic memory errors

Write at the end:


mind Mapping:

1. Why does dynamic memory allocation exist

We have now learned some ways of memory allocation:

int main()
{
	int i;//在内存栈区开辟4个字节空间
	char arr[5];//在栈空间上开辟5个字节的连续空间
	return 0;
}

However, the memory allocated in this way is static and fixed:

1. The space allocation size is fixed.

2. When declaring an array, the length of the array must be specified, and the memory it needs will be allocated at compile time.

If you want to open up space during compilation, you need to use dynamic memory.

2. Introduction to dynamic memory functions

2.1 malloc

void* malloc (size_t size)

2.2 free

void free (void* ptr)

example:


#include <stdio.h>
#include <stdlib.h>

int main()
{
	//申请40给字节,用来存放10个整形
	int* p = (int*)malloc(40);//malloc申请的空间不会初始化
	if (p == NULL)            //直接返回起始地址
	{
		perror("malloc");//如果空间开辟失败要报错并返回
		return 1;
	}

	//使用空间
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d\n", *(p + i));
	}

	//释放申请的内存
	free(p);
	p = NULL;
	return 0;
}

output:

输出:
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451

malloc doesn't initialize itself, so it prints random values.

example:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	//申请40给字节,用来存放10个整形
	int* p = (int*)malloc(40);//malloc申请的空间没有初始化
	if (p == NULL)            //直接返回起始地址
	{
		perror("malloc");//如果空间开辟失败要报错并返回
		return 1;
	}

	//使用空间
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p + i) = i + 1;//初始化赋值
		printf("%d ", *(p + i));
	}
	//释放申请的内存
	free(p);
	p = NULL;
	return 0;
}

output:

输出:1 2 3 4 5 6 7 8 9 10

2.3 calloc

void* calloc (size_t num, size_t size)

example:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p = (int*)calloc(10, sizeof(int));//10是要初始化的个数,sizeof(int)是每个的大小
	if (NULL == p)
	{
		perror("calloc");//判断内存是否申请成功
		return 1;
	}

	//使用
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p + i));//calloc申请空间后,会把空间初始化成0
	}                                              //再返回起始地址

	//释放
	free(p);
	p = NULL;
}

output:

输出:0 0 0 0 0 0 0 0 0 0

2.4 realloc

void* realloc (void* ptr, size_t size)

The realloc function can append more dynamic memory.

example:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p = (int*)malloc(5 * sizeof(int));//开辟一段动态内存20个字节
	if (NULL == p)
	{
		perror("malloc");//检查是否创建成功
		return 1;
	}
	
	//使用
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		*(p + i) = i + 1;
	}

	//不够用,增加5个整形的空间
	int* ptr = (int*)realloc(p, 10 * sizeof(int));//这里是开辟到40个字节
	//realloc函数开辟内存空间有两种情况:
	//1.原内存块后面空间足够,在原内存块后面追加内存
	//2.原内存块后面空间不够,另外找一片区域开辟内存,将原内存块释放

	if (ptr != NULL)
	{
		p = ptr;//为什么不直接用p接收?
		//如果内存追加失败,直接用p接收的话,原本已经开辟的动态内存空间就会被覆盖
	}

	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p + i));
	}

	//释放
	free(p);
	p = NULL;
	return 0;
}

output:

输出:1 2 3 4 5 -842150451 -842150451 -842150451 -842150451 -842150451

3. Common dynamic memory errors

example 1:

Remember to judge when opening up dynamic memory, and finally release the memory.

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p = (int*)malloc(100);
	//内存开辟后没有判断是否开辟成功
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p + i) = 0;//危险代码,我们无法知道是否存在非法访问
	}
	//并且最后也没有将开辟的内存还给操作系统
	return 0;
}

Example 2:

Use as much dynamic memory as you have allocated, and be careful of out-of-bounds access.

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int* p = (int*)malloc(100);//开辟了100字节空间

	//判断
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}

	int i = 0;
	for (i = 0; i < 100; i++)//造成越界访问
	{
		*(p + i) = 0;//一个整形4个字节
	}

	//释放
	free(p);
	p = NULL;
	return 0;
}

Example 3:

Do not free up other memory spaces.

int main()
{
	int a = 10;
	int* p = &a;
	//你没有权限乱释放其他的内存空间
	free(p);//不能对栈区的内存释放
	return 0;
}

Example 4:

Do not free memory space multiple times.

#include <stdio.h>
#include <stdlib.h>

int main()
{
	//开辟空间
	int* p = (int*)malloc(100);

	//判断
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}

	//使用
	int i = 0;
	for (i = 0; i < 25; i++)
	{
		*p = i;
		p++;//p指针不断往后移动
	}

	//释放的时候指针应该指向起始地址,否则程序又会出错
	free(p);
	p = NULL;

	return 0;
}

Example 5:


#include <stdio.h>
#include <stdlib.h>

int main()
{
	//创建
	int* p = (int*)malloc(100);
	
	//判断
	if (p == NULL)
	{
		return 1;
	}

	//释放
	free(p);

	free(p);//已经释放了,重复释放会导致程序出错

	return 0;
}

This is about the benefits of setting it as a null pointer at the end:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	//创建
	int* p = (int*)malloc(100);
	
	//判断
	if (p == NULL)
	{
		return 1;
	}

	//释放
	free(p);
	p = NULL;//置为空指针后程序就不会崩溃了

	free(p);//p为空指针时,程序不会报错

	return 0;
}

Example 5:

Remember to release or return the address in time if you open up dynamic memory when implementing the function.

Otherwise, that memory space will no longer be found, which will eventually lead to a memory leak.

#include <stdio.h>
#include <stdlib.h>

void test()
{
	int* p = (int*)malloc(100);
	//忘记释放
}//出了函数就找不到了,因为变量p被销毁了
//造成内存泄漏

int main()
{
	test();
	return 0;
}

Example 6:

This question is also similar:

#include <stdio.h>
#include <stdlib.h>

void test()
{
	int* p = (int*)malloc(100);
	if (p == NULL)
	{
		return;
	}

	//使用
	if (1)
		return;//出问题//内存泄漏

	//释放
	free(p);
	p = NULL;
}

int main()
{
	test();
	return 0;
}

Beware of memory leaks and remember to free up space.

Write at the end:

The above is the content of this article, thank you for reading.

If you like this article, please like and comment, and write down your opinions.

If you want to learn programming with me, you might as well follow me, we will learn and grow together.

I will output more high-quality content in the future, welcome to watch.

Guess you like

Origin blog.csdn.net/Locky136/article/details/128306776