成都网站建设设计

将想法与焦点和您一起共享

C语言的动态内存的分析-创新互联

1.动态内存

示例:

公司主营业务:成都网站制作、成都做网站、外贸营销网站建设、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联推出芷江免费做网站回馈大家。

运行时程序崩溃。这是为什么呢?再次分析编译链接过程

栈区∶我们知道栈区在函数被调时分配,用于存放函数的参数值,局部变量等值。在windows 中栈的默认大小是1M,在vs 中可以设置栈区的大小。在Liunx中栈的默认大小是10M,在gcc编译时可以设置栈区的大小。
堆区:程序运行时可以在堆区动态地请求一定大小的内存,并在用完之后归还给堆区。在Liunx系统中堆区的大小接近3G。

  windows :栈:1M      堆1.5G~1.9G
  Linux  :栈  10M    堆 1.5G ~3G
一般情况下我们需要大块内存或程序在运行的过程中才知道所需内存大小,我们就从堆区分配空间。

2.动态内存分配函数

C语言中动态内存管理的有四个函数:malloc,calloc, realloc,free,都需要引用stdlib.h或malloc.h文件,但是也存在一些差异

malloc

malloc向堆区申请一块指定大小的连续内存空间。

int* p=(int*)malloc(100 * sizeof(int));
	assert(p != NULL);
	memset(p, 0, 100 * sizeof(int));

其原型 *void malloc(unsigned int num_bytes);
num_byte为要申请的空间大小,需要我们手动的去计算,如int *p = (int *)malloc(20 *sizeof(int)),如果编译器默认int为4字节存储的话,那么计算结果是80Byte,一次申请一个80Byte的连续空间,并将空间基地址强制转换为int类型,赋值给指针p,此时申请的内存值是不确定的。

int main()
{
	//windows :栈:1M      堆1.5G~1.9G
	//Linux  :     10M          ~3G
   // int arr[100];

	char* p = (char*)malloc(1.5 * 1024 * 1024 * 1024);
	if (p == NULL) {
		printf("失败\n");
     }
	else {
		printf("成功\n");
		free(p);
		p = NULL;
	}
return 0;
}

malloc 申请未初始化的堆内存  +for/memset 

int* p=(int*)malloc(400);

calloc函数

  其原型void *calloc(size_t num, size_t size);
  其比malloc函数多一个参数,并不需要人为的计算空间的大小,比如如果他要申请20个int类型空间,会int *p = (int *)calloc(20, sizeof(int)),这样就省去了人为空间计算的麻烦。但这并不是他们之间最重要的区别,malloc申请后空间的值是随机的,并没有进行初始化,而calloc却在申请后,对空间逐一进行初始化,并设置值为0;  

  callot申请已被初始化的堆内存  (类型默认值)

  malloc + for<=>calloc
  int *p = (int *)calloc(20, sizeof(int))

#include
#include#include#include//memset
//C语言中动态内存管理的有四个函数:malloc,calloc, realloc,free,都需要引用stdlib.h或malloc.h文件。
//栈: 系统管理  堆:程序员自己开辟,自己释放


int main()
{
	//int 100
	int* p=(int*)calloc(100, sizeof(int));  //元素数目
	assert(p != NULL);

	for (int i = 0; i< 100; i++)
	{
		printf("%5d", p[i]);
	}

	free(p);
	p = NULL;
return 0;
}

realloc函数

realloc函数和上面两个有本质的区别,其原型void *realloc(void *ptr, size_t new_Size)
用于对动态内存进行扩容及已申请的动态空间不够使用,需要进行空间扩容操作,ptr为指向原来空间基址的指针, new_size为接下来需要扩充容量的大小。

free:

  free:释放动态内存 ,不释放会出现内存泄漏(C/C++ 非常麻烦的问题)
 泄漏的内存被回收的情况:1.进程(运行的该程序)结束;2.关机

代码示例:

//初始化函数
void init(PArr parr){
	assert(parr != NULL);
	parr->element = (int*)malloc(CAPACITY*sizeof(int));
	assert(parr->element != NULL);
	parr->length = CAPACITY;
	parr->size = 0;
}

//数组的尾部插入value
void addtail(PArr parr, int value) {
	//数组容量不足(判满操作),考虑扩容
	if (parr->size == parr->length) { //扩容 realloc
		int* newelement = (int*)realloc(parr->element,parr->length*2*sizeof(int));
		if (newelement == NULL) { //扩容失败
			exit(EXIT_FAILURE);
		}
		parr->element = newelement;
	}

	parr->element[parr->size++] = value;
}
//头部删除元素value  [1 2 3,,,,,,]
void removehead(PArr parr);
//查找返回下标
int searchvalue(PArr parr, int value);
//修改元素
void change(PArr parr, int oldv, int newv);
typedef struct Array {
	int* element;
	int size; //有效数据元素个数
	int length; //数组容量
}Array, * PArr;

void init(PArr parr); //初始化函数
//数组的尾部插入value
void addtail(PArr parr, int value);
//头部删除元素value  1 2 3 4
void removehead(PArr parr);
//查找返回下标
int searchvalue(PArr parr, int value);
//修改元素
void change(PArr parr, int oldv, int newv);
#include "array.h"
#includeint main() {
	Array array;
	init(&array);
	addtail(&array,1); //1
	addtail(&array, 2); // 1 2
	addtail(&array, 3); // 1 2 3
	addtail(&array, 4); // 1 2 3 4

	int index = searchvalue(&array, 3);
	printf("%d\n",index);

	return 0;
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


分享文章:C语言的动态内存的分析-创新互联
文章地址:http://chengdu.cdxwcx.cn/article/diispj.html