malloc、calloc、realloc函数

目录

一、malloc函数

二、free函数

三、calloc函数

 四、realloc函数

 五、动态内存错误类型

5.1 对NULL指针的解引用操作

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

5.3 对静态开辟内存使用free释放

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

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

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


一、malloc函数

静态开辟内存空间的方式有:int a[5]、char c等,特点是:空间开辟大小固定,数组在定义时指定大小。

malloc函数的作用是动态开辟内存空间,库,声明:void* malloc (size_t size)。malloc函数有以下几点需要注意:

==开辟成功,则返回一个指向开辟好空间的指针

==开辟失败,则返回一个NULL指针。返回值的类型是 void* 

==返回值的类型是 void*,因此malloc的返回值一定要做检查

==若参数 size 为0,malloc的行为是标准是未定义的,取决于编译器

二、free函数

free函数只能用来释放malloc、calloc、realloc等动态开辟空间函数开辟的内存,无法释放静态开辟的内存。库,声明:void free (void* ptr)。注意:

==指向动态开辟的空间

==free(NULL),函数什么都不做.

现在就malloc、free函数举个例子:

#include 
#include 
int main()
{
	int* ptr = (int*)malloc(100);//开辟100个字节的内存
	if (NULL == ptr)//判断ptr指针是否为空
		return 1;
	int i = 0;
	for (i = 0; i < 100; i++)
	{
		*(ptr + i) = i;
	}
	free(ptr);//释放ptr所指向的动态内存
	ptr = NULL;//最好将NULL赋给ptr
	return 0;
}

三、calloc函数

 

calloc函数功能类似malloc,也可以开辟空间。库,声明:void* calloc (size_t num, size_t size);

==函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0

==calloc会在返回地址之前把申请的空间的每个字节初始化为全0,而malloc不初始化

#include
#include
#include
int main()
{
	int* p = (int*)calloc(10, sizeof(int));
	if (p == NULL)
	{
		printf("%d\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(p);
	p = NULL;
	return 0;
}

内存监视显示开辟的10个整型空间全部初始化为0

malloc、calloc、realloc函数_第1张图片malloc、calloc、realloc函数_第2张图片

 四、realloc函数

realloc 函数的作用是对动态开辟内存调整大小。库,声明:void* realloc (void* ptr, size_t size)

==ptr 是要调整的内存地址,size 是调整之后的新大小,返回值为调整之后的内存起始位置

==若原有空间之后有足够大的空间,扩展内存就直接在原有内存之后直接追加空间,原来空间的数据不发生变化;若原有空间之后没有足够大的空间,在堆空间上另找一个合适大小的连续空间来使用,函数返回一个新的内存地址

malloc、calloc、realloc函数_第3张图片

 五、动态内存错误类型

5.1 对NULL指针的解引用操作

#include
#include
int main()
{
	int* p = (int*)malloc(1000000);
	for (int i = 0; i < 1000000; i++)//若开辟内存失败,p为NULL,对NULL解应用会引起程序崩溃
		*(p + i) = i;
	return 0;
}

malloc、calloc、realloc函数_第4张图片

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

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

5.3 对静态开辟内存使用free释放

void test()
{
  int a = 10;
  int *p = &a;
  free(p);//free只能释放malloc\calloc\realloc开辟的空间
}

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

void test()
{
  int *p = (int *)malloc(100);
  p++;
  free(p);//p不再指向动态内存的起始位置,释放部分动态开辟内存不可行
}

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

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

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

void test()
{
	int* p = (int*)malloc(100);//p是局部变量
    //...
	if(flag == 1)
		return;
	//...
    free(p);//因为某些原因导致直接跳过free(P),内存未释放,且P为test内的临时变量,程序结束找不 
    到开辟动态内存的起始地址,造成内存泄露
    p=NULL;
}
int main()
{
	test();
}

你可能感兴趣的:(c++)