c语言动态内存管理相关知识点

1.前引

设置变量后,该变量所开辟的空间就已经定死了,但是实现一个项目时未利用到开辟空间的变量就会造成浪费,而且如果变量的内存有限也可能造成数据无法完全保存。所有引入一个操作位开辟动态内存,这个操作可以根据用户来自己拟定需要多大内存实现操作。

栈区:局部变量,形式参数

堆区:malloc,calloc,realloc,free

静态区: 全局变量,静态变量

2.malloc

void *malloc( size_t size );

 开辟一块空间,括号内为开辟空间的字节大小,返回为这个空间的指针;

如果括号内为0,该行为未定义;

如果这个空间开辟失败返回的指针为NULL,所以如果指针为空说明并没有开辟成功;

开辟的指针要根据自己需要重新转化为需要的指针;

开辟的空间为未初始化;

 3.free

void free( void *memblock );

该函数用于释放开辟的空间;

释放的原因:当用完一个空间后,这个空间仍然存在,这样就会占着内存,并且如果开辟的过多不及时释放,空间会出现内存碎片降低存储信息的效率,所以需要将不需要的空间进行释放(不释放造成内存泄漏);

释放空间后,指针的地址仍然存在,这样会造成野指针,所以当释放掉空间后也需要把空间的指针变为空指针;

int main()
{
	int* pf = (int*)malloc(40);
	if (pf == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(pf + i) = i;
		printf("%d ", *(pf + i));
	}
	free(pf);
	pf = NULL;
	return 0;
}

perror():是一个打印错误信息的函数,这里用于判断出是否已经开辟出动态内存;

return 1 :为固定格式表明该代码出现错误;

4.calloc

void *calloc( size_t num, size_t size );

开辟num给元素,每个元素,size大小的字节,并且内存已经初始化

5.realloc

void *realloc( void *memblock, size_t size );

memblock:需要调整的块的地址;

size:新调整的大小;

工作原理:先判断扩容的空间放不放的下,放不下就拉倒返回NULL指针,如何看如果放得下就有两种情况:1.后面扩容没东西挡着,所以就在原来指针开辟的空间后面扩容 2.后面有挡着的,则换一个放得下这么大内存的地方,把之前的块里的东西复制到现在的块中,并且返回现在的地址

int main()
{
	int* pf = (int*)malloc(40);
	if (pf == NULL)
	{
		perror("malloc");
		return 1;
	}
	int* ptr = realloc(pf, 80);
	if (ptr == NULL)
	{
		perror("malloc");
		return 1;
	}
    else
    {
        pf = ptr;
        ptr=NULL;
    }
	for (int i = 0; i < 20; i++)
	{
		*(pf + i) = i;
		printf("%d ", *(pf + i));
	}
	free(pf);
	pf = NULL;
	return 0;
}

实现realloc函数时要用另外的指针来接受地址(为了防止空间开辟失败导致原指针指向的地方失效,空间永远无法回收),如何再用原来的指针接收,并且把多余的指针变回NULL指针,以免非法使用

6.动态内存管理几种错误

1.NULL指针无法被释放(free)

措施:在操作前先判断指针是否为空指针NULL;

2.动态内存越界访问

3.非动态开辟的空间释放

注意:其实可以拓展一下,不是堆区的变量就不能拿来做堆区的操作;

4.部分释放

措施:如果要访问指针后面的内容,可以在指针后加偏移量;或者指针重新设置一个指针,一个记录块的地址,一个作为使用的地址,操作结束后记得把使用的指针变为NULL;

5.多次释放

6.不释放(内存泄漏) 

7.柔性数组

结构体最后一个成员为未确定元素的数组为柔性数组

typedef struct st_type
{
int i;
int a[];//柔性数组成员,有时候[]内可以是0;
}type_a;

sizeof()不计算柔性数组的大小;

开辟空间要用到动态内存函数

struct S
{
	int a;
	int arr[];
};

int main()
{
	struct S* p = (struct S*)malloc(sizeof(struct S) + 40);
	if (p = NULL)
	{
		perror("malloc");
		return 1;
	}
	p->a = 10;
	for (int i = 0; i < 10; i++)
	{
		p->arr[i] = i + 1;
	}
	struct S* ptr = (struct S*)realloc(sizeof(struct S) + 80);
	if (ptr != NULL)
	{
		p = ptr;
		ptr = NULL;
	}
	else
	{
		peeror("realloc");
		return 1;
	}
	free(p);
	p = NULL;
	return 0;
}

你可能感兴趣的:(C,c语言)