malloc :
malloc:void* malloc(size_t size);
申请空间 ->设置这片空间的开始周期
- size:要申请多少字节
- size_t:无符号整数类型(专门用来表示大小、长度、个数)
- 返回值: 成功 → 返回内存首地址 失败 → 返回
NUL
举例:
int* p = (int*)malloc(40);
申请 40 字节堆内存,用 int 指针 p 接收*
3 条铁律
- malloc 申请的是堆内存
- 必须判断是否 == NULL
- 必须手动 free,否则内存泄漏
calloc:
calloc:void* calloc(size_t num, size_t size
num:元素个数size:单个元素字节大小总字节数 = \(num \times size\)
- 从堆区申请内存
- 自动把内存全部初始化为 0
- 返回
void*,使用要强转类型
举例:
int *p = (int*)calloc(5, sizeof(int));
申请5个int空间,初始全0
malloc与calloc:
1.calloc功能和malloc一模一样:在堆区申请一片空间设置这个空间的出生周期
2.区别一:malloc申请size个字节 calloc申请num*size个字节
3.区别二:malloc对所有的字节按照cd进行填充 calloc对所有的字节按照00进行填充
malloc与calloc申请空间判断是否合法
#include<stdio.h>
#include<stdlib.h>
int main() {
int* p = (int*)malloc(40);
if (p==NULL) {
printf("申请空间不足\n");
return 0;
}
printf("扩容前:%p\n",p);
int* q = (int*)realloc(p, 80);
if (q == NULL) {
printf("扩容空间不足\n");
return 0;
}
printf("扩容后:%p\n", q);
return 0;
}
realloc:
realloc:void* realloc(void* ptr, size_t new_size);
ptr:原来 malloc / calloc / realloc 出来的指针
size_t:无符号整数类型(专门用来表示大小、长度、个数)
new_size:新的总大小(不是增加多少!)
返回值:新内存的地址
三种工作情况
- 原内存后方空闲空间充足:原地扩容,地址不变
- 后方空间不足:新开辟内存,自动拷贝旧数据,释放旧内存,返回新地址
- 扩容失败:返回 NULL,原内存保留不动
free:
free:void free(void* ptr);
void* ptr接收任意类型的指针
free:释放你用 malloc / calloc / realloc 申请的堆内存
你可以把堆内存想象成:你租的一间房子
malloc = 租房子
realloc = 换更大/更小的房子
free = 退房
free(p);
p = NULL;
free (p) 后不写 p=NULL,语法没错,但非常危险!
free(p)= 归还内存- p 本身的值没变 → 变成野指针
-
free 之后 p 变成 野指针你再用
*p或p[i]就是:非法闯入别人的房子!
free的正确释放
free只可释放堆区的第一个(起始)地址
free : 释放空间,设置这片空间的结束周期.
free 只是释放内存不是结束程序!
例题用realloc1~10扩容至1~20:
#include<stdio.h>
int main() {
// 堆区申请空间 40Byte(1~10)
int* p = (int*)malloc(40);
if (p == NULL) {
printf("申请空间太大 申请失败\n");
return;
}
for (int i = 0; i < 10; i++) p[i] = i + 1;
printf("扩容前:");
for (int i = 0; i < 10; i++) printf("%d ", p[i]);
printf("\n");
// 扩容 需要放1~10 + 11~20
int* q = (int*)realloc(p, 80);
if (q == NULL) {
printf("扩容空间太大 申请失败\n");
return 0;
}
// 核心:更新指针
p = q;//将第一个地址都给p
q = NULL;//销毁q的地址 置空
for (int i = 10; i < 20; i++) p[i] = i + 1;
printf("扩容后:");
for (int i = 0; i < 20; i++) printf("%d ", p[i]);
printf("\n");
if (p == q) {
printf("p之前40Byte后续还有连续空余的40Byte\n");
}
// 释放空间
free(p);
// 将之前保存的地址彻底抹去,避免发生非法访问
p = NULL;
}
5363

被折叠的 条评论
为什么被折叠?



