C语言——动态内存管理入门

动态内存管理

一.动态内存的意义。

我们之前能够分配内存的方式有:直接定义变量或者开辟一个固定大小的数组。

int a=10;
int a[10];

上述开辟内存的方式都是在栈内,并且是在编译时分配。

但是我们通常所需的看空间都是在运行时才知道,此时就需要动态开辟内存了。

2.接下来看看计算机中内存的划分。这是在Linux下的内存分布情况。

C语言——动态内存管理入门

先展示一段代码来表示这些变量在内存中的存储情况:

#include <stdio.h>
#include <stdlib.h>
//定义一个函数
void A(){
    ;
}

int global=0;//定义一个全局变量

int main(){
    int* p=(int *)malloc(sizeof(int));    //用malloc动态开辟一段内存空间
    int a;            //定义一个局部变量
    printf("funcA=%p\n",A);
    printf("global=%p\n",global);
    printf("p=%p\n",p);
    printf("&a=%p\n",&a);
    return 0;
}

结果如下:Linux下。

C语言——动态内存管理入门

从执行结果可以看出:函数、全局变量、动态开辟的空间、局部变量的地址就如上图那样从高到低。

三.几种动态分开辟内存的方式

1.malloc与free

函数原型:

void* malloc(size_t size);

void free(void * ptr);

malloc所开辟的空间是在堆上分配的,堆上的空间比栈要大很多,但是也是有限度的。

当malloc分配空间成功时,会返回开辟成功的空间的地址,分配失败,则会返回NULL;

	int *p = (int*)malloc(sizeof(int));
	*p = 444;
	printf("%p,%d\n", p, *p);
	free(p);
	printf("%p\n", p);

运行结果:

C语言——动态内存管理入门

 

注意:

(1).malloc后必须free,否则就会内存泄漏。

(2).free后的空间并没有指向空,只是将那段空间的值释放了。

(3).malloc的变量不能多次free,只能free一次,否则还是内存泄漏。

(4).为了避免这种访问到已经free的内存,我们可以在free后就让指针变量指向NULL。这样一旦对空指针解引用,我们就会很快的发现错误。

(5).一般对malloc所开辟的空间都需要进行成功与否的判断,如果分配失败它就会返回一个空指针。

2.calloc

函数原型:

void* calloc(size_t num, size_t size);

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

	int *p = calloc(10, 4);
	printf("%d\n", *p);
	int *pp = (int *)malloc(sizeof(int)*10);
	printf("malloc时候:%p\n", pp);
	pp = realloc(pp, 500);
	if (pp == NULL) {
		printf("realloc时候:pp是空!!!\n");
	}
	else {
		printf("realloc时候:pp非空!!!\n%p\n",pp);
	}

执行结果:

C语言——动态内存管理入门

3.realloc

函数原型:

void* realloc(void* ptr, size_t size);

函数功能:扩容:

如果原有空间有足够的空间,那么就玩原来的空间后面直接“续”。

如果原有空间后面没有足够的空间,就新开辟一段空间。

C语言——动态内存管理入门

 

C语言——动态内存管理入门

C语言——动态内存管理入门

 

总结:

1.malloc与free,malloc必须free

2.动态分配内存不忘判断是否分配成功。