浅谈动态内存管理

动态内存管理

为什么存在动态内存管理?

  在过去我们学的数组或者直接使用变量来开辟空间,这个空间是处于上的,在空间开辟的时候大小就是固定的,不能改变,因此当开辟的空间不够时,这种方式就无法满足了,故我们引入动态内存的开辟方式。

动态内存函数

malloc和free

 void* malloc(size);

  这句代码的含义是向内存中申请一块连续的空间,是位于上的,并且返回一个这块空间的指针。如果开辟成功返回一个这块空间首地址的指针,如果开辟失败返回一个NULL指针,因此,这里需要对malloc后的返回值进行一个检查。malloc的返回值是一个void*,因此返回值的类型我们是可以自己定义的,如果参数size的值为0,malloc的行为标准是未定义的,取决于编译器。

void free(void* ptr);

  free函数是用来释放动态开辟的内存的,如果参数ptr指向的空间不是动态开辟的,那么free函数的行为是未定义的,如果ptr是NULL指针,则函数什么都不做。
  malloc和free都声明在stdlib.h头文件中

calloc

原型:

void* calloc(size_t num, size_t size)

功能:
  为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0,这里注意一个误用,calloc只能初始化为0,不能初始化为其他数字。与malloc的区别也只是有着初始化为0的区别。

realloc

原型:

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

功能:
  如果在过去我们感觉申请的空间太小,relloc可以再申请的空间,如果第二次申请的空间比较小,再内存中原本的地址能连续的申请成功,那么ptr的地址是不会改变的,但是如果申请的新空间比较大,在原本的位置申请的话无法连续,那么就会重新开辟一个空间,并且系统会把原本的值赋到新空间上,并把原来的空间释放掉,ptr是需要扩容的空间的首地址,size是调整后的大小,一般是在原来基础上扩容1.5倍-2倍。返回值为扩容后空间的首地址。

常见的动态内存的错误

1.对NULL指针的解引用操作

void test()
{
	int *p = (int *)malloc(INT_MAX/4);
	*p = 20;//如果p的值是NULL,就会有问题
	free(p);
}

  申请完空间需要先判断指针p是否为NULL。

2.对动态开辟空间的越界访问

void test()
{
	int i = 0;
	int *p = (int *)malloc(10 * sizeof(int));
	if (NULL == p)
	{
		exit(EXIT_FAILURE);
	}
	for (i = 0; i <= 10; i++)
	{
		*(p + i) = i;//当i是10的时候越界访问
	}
	free(p);
}

  只申请的40个字节的空间,因此只能到下标9。

3.对非动态内存开辟内存使用free释放

void test()
{
	int a = 10;
	int *p = &a;
	free(p);//ok?
}

  free主要是释放malloc出来的空间,这类空间是在堆上的,而代码中的空间是在栈上开辟的。

4.使用free释放一块动态开辟内存的一部分

void test()
{
	int *p = (int *)malloc(100);
	p++;
	free(p);//p不再指向动态内存的起始位置
}

  内存释放要释放就一起释放。

5.对同一块动态内存多次释放

void test()
{
	int *p = (int *)malloc(100);
	free(p);
	free(p);//重复释放
}

6.动态开辟内存忘记释放(内存泄漏)

void test()
{
	int *p = (int *)malloc(100);
	if (NULL != p)
	{
		*p = 20;
	}
}
int main()
{
	test();
	while (1);
}

柔性数组

原型:

typedef struct st_type
{
	int i;
	int a[0];//柔性数组成员
}type_a;

柔性数组的特点:

  1. 除了柔性数组之外,结构体中必须还包含至少一个其他成员,并且柔性数组成员在结构体的最后。
  2. 使用sizeof返回结构体的大小时,不计算柔性数组的内存。
  3. 柔性数组的大小用malloc进行分配,分配多出来的空间就是柔性数组的大小,因此,分配的空间应该大于结构体的空间。

猜你喜欢

转载自blog.csdn.net/weixin_43580319/article/details/113131526