嵌入式Linux开发《C语言专题(五:(3)实用的内存函数总结7)》

在文章嵌入式Linux开发《C语言专题(五:(3)实用的内存函数4)》嵌入式Linux开发《C语言专题(五:(3)实用的内存函数5)》嵌入式Linux开发《C语言专题(五:(3)实用的内存函数6)》中对C语言中内存操作函数malloc&free做了详细介绍。这篇文章主要讲剩余的calloc&realloc以及简要总结内存函数之间的区别和联系。

(1)calloc:申请内存

函数名:calloc

函数原型:void *calloc(size_t nmemb, size_t size);

函数参数nmemb:内存块的个数

size:以字节为单位申请的每个内存块的大小

头文件: #include <stdlib.h>

功能:动态申请内存并且内存被初始化为0

返回值:成功返回执行分配内存的地址 失败返回NULL

说明:calloc的任意一个参数为0也可能返回NULL或者是一个独特的指针,这个指针随后传递给free。实际开发中这样操作是无意义的,

代码演示

#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h> 
//申请4个
#define NUMBER 4
//演示使用calloc申请内存
int main(int argc, char** argv)
{
	int i = 0;
	int *p = NULL;
	//第一步:申请内存空间
	p = (int *)calloc(NUMBER, sizeof(int));
	//第二步:检查返回值
	if(NULL == p)
	{
		printf("申请内存空间出错");
		//如果出错,退出整个进程
		exit(-1); 
	}
	
	printf("赋值之前:");
	for(i=0; i<NUMBER; i++)
	{
		printf("p[%d] = %d ", i, p[i]);
		printf(" %p \t", &p[i]);
	}
	printf("\n");
	
	printf("赋值之后:");
	//第三步:使用内存空间
	for(i=0; i<NUMBER; i++)
	{
		//将所申请的内存空间赋值为1
		p[i] = 1;
		printf("p[%d] = %d \t", i, p[i]);
	}
	printf("\n");
	
	//第四步:释放内存空间
	free(p);
	p = NULL; 
	
	return 0;	
}

分析结果:未赋值前,申请的内存地址中的值确实为0;同时从结果输出的地址值可以看出申请的内存空间确实是连续的。其实p = (int *)calloc(NUMBER, sizeof(int));也可以换成p = (int *)malloc(NUMBER* sizeof(int))。

(2)realloc:修改原来已经申请的内存块大小

函数名:realloc

函数原型:void *realloc(void *ptr, size_t size);

函数参数:size:以字节为单位申请的内存大小

头文件: #include <stdlib.h>

功能:改变由参数ptr所指向的内存块的大小为参数size

返回值:成功返回新分配的内存地址 失败原来的内存会留下,不会释放或者移动

说明如果参数size值大于原来的size,则多余的大小将不会被初始化;如果ptr为NULL,

等价于malloc(size);如果size为0,ptr不为NULL,等价于free(ptr); 如果ptr不为

NULL,那么ptr一定是通过malloc(), calloc()或者realloc()返回的值.

代码演示

#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h> 
//申请4个
#define NUMBER 4
//演示使用realloc改变申请的内存空间大小
int main(int argc, char** argv)
{
	int i = 0;
	int *p = NULL;
	//第一步:申请内存空间
	p = (int *)calloc(NUMBER, sizeof(int));
	//第二步:检查返回值
	if(NULL == p)
	{
		printf("申请内存空间出错");
		//如果出错,退出整个进程
		exit(-1); 
	}
	//原来申请的内存大小为NUMBER*sizeof(int)=16字节
	//现在改成sizeof(double)*4=32字节 刚好够存储8个整型数
	p = (int *)realloc(p, sizeof(double)*4);	
	printf("赋值之前:");
	for(i=0; i<NUMBER*2; i++)
	{
		printf("p[%d] = %d ", i, p[i]);
		printf(" %p \t", &p[i]);
	}
	printf("\n");
	
	printf("赋值之后:");
	//第三步:使用内存空间
	for(i=0; i<NUMBER*2; i++)
	{
		//将8个整型数的内存空间赋值为1
		p[i] = 1;
		printf("p[%d] = %d \t", i, p[i]);
	}
	printf("\n");
	
	//第四步:释放内存空间
	free(p);
	p = NULL; 
	
	return 0;	
}

分析结果:原来申请的内存大小为NUMBER*sizeof(int)=16字节 现在改成sizeof(double)*4=32字节 刚好够存储8个整型数 因此可以对申请的32个地址空间进行赋值操作。

(3)malloc和calloc的联系与区别?

联系:都是用来动态申请内存。

区别:

1)malloc所申请的内存空间没有被初始化,而calloc所申请的内存空间被初始化为0;

2)申请的内存方式不一样:从他们各自的参数就可以看出,malloc直接申请所需的内存空

间,而calloc是分为2部分内存块数量和每一个内存块的大小,总的内存空间=内存块数量

*每一个内存块的大小

内存函数操作部分即将写完,希望读者可以理解在嵌入式Linux开发《C语言专题(五:(3)实用的内存函数5)》文章中所提出的几个问题:什么是动态内存分配?什么是静态内存分配?动态内存分配和静态内存分配的区别和联系?

最后总结在实际的研发时要具体问题具体对待,选择合适的内存函数来进行操作。除此之外还有一些我们在使用需要注意的地方:

1)最好使用sizeof计算数据类型的长度,因为具有移植性。

2)及时检查malloc的返回值,最好对malloc的返回值进行强制类型转换到我们想要的类型。

3)不访问动态内存之外的区域。

3)用free函数时参数一定是malloc、calloc或者realloc的返回值。

4)在free释放申请的动态内存后,不再进行访问。

5)不能用free只释放所申请的动态内存的一部分。

6)malloc或者calloc后者realloc和free配对使用。

未完待续,后续继续更新...

更多精彩内容可以关注此头条号:嵌入式软硬件开发 喜欢的话大家可以“评论”,“转发”、“点赞”或者“收藏”,感谢大家。相互交流,共同成长。

举报
评论 0