C语言的动态内存的分析

 1.动态内存

 示例:

C语言的动态内存的分析_第1张图片

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

 C语言的动态内存的分析_第2张图片

     栈区∶我们知道栈区在函数被调时分配,用于存放函数的参数值,局部变量等值。在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;
}

C语言的动态内存的分析_第3张图片

 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;
}

C语言的动态内存的分析_第4张图片

realloc函数

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

 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"
#include 

int 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;
}

你可能感兴趣的:(C语言,c语言)