C语言基础知识之(十八):堆内存的分配函数及运用

由开发人员负责分配和回收的内存区:堆区

1、特点:

由开发人员分配和回收。如果没有回收会造成程序泄露,导致程序崩溃。

2、堆区分配内存的函数

作用:

指定分配存储空间的大小(字节数),将分配的存储空间的起始地址返回。

堆内存是使用地址操作的,地址存储在对应的指针变量中。

 

Malloc函数

语法:

void * malloc(size)

说明:

void * 表示无类型指针

size 表示分配多大的存储空间,单位是字节数。

Malloc分配的内存空间不会把原内存的数据清空。

如:在堆区存储n个整型数

int * p =malloc(sizeof(int) * n);

每个整形数的字节数是:sizeof(int),分配几个就乘以几。

 

在堆区存储4个整型数(4个整型数的存储空间是连续的),分别把21、22、23、24存储在堆区。指针名可以当做数组名使用,都指向数组的首元素地址。

int * r =malloc(sizeof(int) * 4);

*r = 21;

*(r+1) = 22;

*(r+2) = 23;

*(r+3) = 24;

for (int i = 0; i< 4; i++) {

    printf("%d\n", *(r+i));

//   printf("%d\n", r[i]);语法糖 数组名[ ]

}

 

在堆区存储一个人名(拼音),分配的是n个连续的存储char类型

char * p =malloc(sizeof(char) * 20);

strcpy(p,"zhangsan");//字符串不能直接赋值,需要使用strcpy函数。

printf("%s\n",p); // %s读取的是字符串的起始地址,字符数组的首地址即p指向的。

 

随机产生10个30~45之间的随机数,存储在堆内存中,在此例中,同样的,指针p的功能可以和数组名一样使用,也可以使用*(p+i).

int * p =malloc(sizeof(int) * 10);

for (int i = 0; i< 10; i++) {

    p[i] = arc4random() % 16 + 30;

    printf("%d ", p[i]);

}

 

 

 

Calloc函数:

void * calloc(int n,size_t size);

语法:

在堆内存中分配n*size个字节的存储空间,并返回地址。

说明:

基本用法和malloc一致,

不同之处:

calloc中字节数的大小和数量分开写。

calloc会将分配的存储空间中的原始数据清空,效率比malloc低。

如:

在堆区存储5个15~35整型数

p = calloc(5,sizeof(int));

for (int i = 0; i< 5; i++) {

    p[i] = arc4random() % 21 + 15;

    printf("%d ", p[i]);

}

 

Recalloc函数:realloc(void*, size_t);

void *realloc(void*p, size_t newSize);

在给定的地址空间(p)基础上,如果当前指针上空间足够,那么将地址扩大,如果空间不足,那么重新找一块新的地址按照newSize大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,然后释放原来的指针指向的内存区域(自动释放,不需要free).

如:

分配存储空间

int * p_old =malloc(10);

重新分配存储空间

int * p_new =realloc(p_old, 20);

printf("%p%p\n", p_old, p_new);

新地址和旧地址随着设定的分配空间的大小而由不同的值。

 

3、内存释放、内存泄露和野指针

堆内存回收,内存释放

语法:voidfree(void *);

例:

在堆内存中存储一个整型数

需要在堆内存存储数据时,分配内存

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

 

使用已经分配好的堆内存

*p = 120;

printf("%d\n",*p);

 

当不需要使用某个内存时,回收内存。

free(p);

注意:这里的内存数据是标记删除。即告诉内存这块区域删除了,而实际上内存的数据扔在内存中,但是无法访问。

 

 

内存泄露:

如果分配的内存在使用后忘记释放,在之后分配的指针又指向没有释放的内存,则称为内存泄露,将会引起程序崩溃。

int *p = NULL;// 此时,指针p是空指针

p =malloc(sizeof(int));// 此时,指针p指向堆内存的某个位置

p =malloc(sizeof(int));// 此时,指针p指向另一个位置

*p = 100;

printf("%d\n",*p);

free(p);// 回收内存

此例在第一个分配的存储空间,出现内存泄露。如果在第二次分配之前加上free(p);这句话,就不会出现内存泄露。

 

 

野指针:通过指针访问了已经被回收的内存

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

*p = 100;

printf("%d\n",*p);

free(p);

 

printf("%d\n",*p)//此时,p是野指针



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值