动态内存开辟malloc,calloc,realloc简述

1.提到动态内存开辟就要想到内存分配的堆区,

静态区,堆区,栈区介绍和区别详情(点击这里

2.动态内存开辟是内申请一定的内存,C语言中与申请内存有关的函数有

malloc,calloc,realloc,free,alloca等函数

(1).malloc

malloc的函数申明:void* malloc(unsigned size);

作用:在内存的动态存储区中分配一块长度为size字节的连续区域,参数size为需要内存空间的长度,返回该区域的首地址.  如果申请失败,则返回NULL指针

malloc分配的内存是位于堆中的,并且没有初始化内存的内容,因此基本上malloc之后,调用函数memset来初始化这部分的内存空间

(2).calloc

calloc的函数申明:void* calloc(size_t numElements, size_t sizeOfElement)

作用:与malloc相似,参数sizeOfElement为申请地址的单位元素长度,numElements为元素个数,即在内存中申请numElements*sizeOfElement字节大小的连续地址空间,相当于在mealloc函数中加了一个memeset。

calloc则将初始化这部分的内存,设置为0.

(3).realloc

realloc的函数申明:void* realloc(void* ptr, unsigned newsize)

作用:给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度.

相当于对已经分配了的内存调整大小

(4).free

动态内存的开辟需要我们自己释放,动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,并立即将指针置位NULL,防止产生野指针。

(5).alloca

alloca是向栈申请内存,因此无需我们自己释放.

3.用法代码示例:

malloc:

#define  _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>

int main()
{
	int *p = malloc(INT_MAX);	//如果申请内存太大,申请失败则返回一个NULL指针
	if(p==NULL)
	{
		printf("%s",strerror(errno));	//如果申请失败,则报错
		return 0;
	}
	free(p);
	return 0;
}

int main()
{
	int *p = calloc(5,sizeof(int));	//申请5个int型元素所占大小空间
	int i = 0;
	for(i=0; i<5; i++)
		printf("%d ",p[i]);	//验证结果全初始化为0
	free(p);
	return 0;
}

int main()
{
	int *p = malloc(20);
	int *str = NULL;
	if(p == NULL)	//检查是否开辟成功
	{
		printf("%s",strerror(errno));
		return 0;
	}
	str = realloc(p,40);//将原先开辟的20字节增加至40字节
	if(str != NULL)
		p = str;	//如果重新开辟空间失败,则不将p替换成str,
	free(p);		//否则p就变成空指针,原来的p指向的内容就无法读取

	return 0;
}

4.常见错误

(1)

void GetMemory(char*p)
{
	p = (char*)malloc(100);
}
void Test(void)
{
	char* str=NULL;
	GetMemory(str);
	strcpy(str,"hello world");
	printf(str);
	free(str);
}
传入的str只是将str临时拷贝一份给形参p,最后str还是NULL。使用strcpy时就会程序崩溃。

应该将str的地址传入,传值的时候再解引用。

(2)想将函数中栈内存中的值返回

char *GetMemory(void) 
{ 
	char p[] = "hello world"; 
	return p; 
} 
void Test(void) 
{ 
	char *str = NULL; 
	str = GetMemory(); 
	printf(str); 
} 
p指针指向的内容在栈中存储,当函数结束时,原先指向的内容已经被清除,

所以现在p指向的内容可能是乱码。

(3)内存泄漏

void GetMemory2(char **p, int num) 
{ 
*p = (char *)malloc(num); 
}
void Test(void) 
{ 
char *str = NULL; 
GetMemory(&str, 100); 
strcpy(str, "hello"); 
printf(str); 
}
没有free(str),会使内存泄漏。

(4)野指针

void Test(void) 
{ 
	char *str = (char *) malloc(100);
	strcpy(str, "hello"); 
	free(str); 
	if(str != NULL) 
	{ 
		strcpy(str, “world”); 
		printf(str); 
	} 
}
free(str)后,没有将str设为空指针,则str变为野指针。(野指针!=NULL)




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值