一、 malloc
- 以前要创建一个长度不确定的数组;为了避免出现问题,只能定义尽可能大的数组,但这样往往会造成空间浪费。现在我们来学习一个新的函数:malloc
- 它可以在堆上开辟一定大小的空间,以指针的形式返回。下面介绍其具体使用方法
void *malloc(size_t size);
- 这就是malloc函数,它只有一个参数(无符号整型),就是要开辟空间的大小。函数的返回值为任意类型的指向所开辟空间的首地址的指针,即malloc并不知道开辟空间的类型,具体有使用者自己决定。
- 注意:如果开辟空间失败,则返回NULL。为了避免错误访问,每次申请空间后都要判断是否申请成功。
int main()
{
int n = 0;
scanf("%d",&n);
int *p = (int*)malloc(n * sizeof(int));
if (p != NULL) {
for (int i = 0; i < n; i++) {
p[i] = i;
}
for (int i = 0; i < n; i++) {
printf("%d ", p[i]);
}
}
system("pause");
return 0;
}
在这里我们使用malloc函数开辟了n个大小为sizeof(int)的地址,并且将返回值强转成int * 赋值给*p。判空后我们对其进行赋值并输出。
二、calloc
void *calloc(size_t num, size_t size);
- calloc函数与malloc函数都是开辟一定大小的空间,不同的是它有两个参数,意为开辟n个大小为size的空间并且将空间内容赋值为0;
int main()
{
unsigned int n = 0;
scanf("%d",&n);
int *p = (int*)calloc(n, sizeof(int));
if (p != NULL) {
for (int i = 0; i < n; i++) {
printf("%d ", p[i]);
}
}
printf("\n");
system("pause");
return 0;
}
三、realloc
- realloc函数是将已经开辟好的空间大小进行重新调整。
void *realloc(void *ptr,size_t size)
-
ptr是要调整的内存地址
-
size是调整之后新大小
-
返回值是调整之后内存起始位置
-
如果是把空间往小了调,则不会改变原指针内容,即原起始地址不变。
-
而如果是把空间往大了调,则有两种情况,
1.直接在原地址后面继续开辟空间,这种情况下原起始地址也不会改变。
2.原来空间后面已经被占用,不能继续在后面开辟,此时,realloc函数会在堆里面重新开辟一段空间,并且把原空间里面的内容拷贝到新空间里。此时原起始地址已经改变。
int main()
{
int n = 5;
int *p = (int*)malloc(n * sizeof(int));
int *p1 = NULL;
n = 10;
int *p1 = (int *)realloc(p, (n * sizeof(int)));
if (p1 != NULL) {
p = p1;
}
system("pause");
return 0;
}
- 刚开始我们用malloc函数开辟了20字节大小的空间,接着用realloc函数将空间调整为40字节。这里我们重新定义了一个指针p1,因为调整空间有可能会失败,如果失败将返回NULL;所以为了保护数据,先由p1指针接收返回值,如果申请成功,再将p1赋值给p。
四、free
void free(void * ptr)
- free函数的作用是将开辟好的堆空间释放掉。
- 释放掉的意思是断开该指针与堆空间的联系,并不会将空间内容清空。
- 如果一直向堆申请空间而不释放,就会造成可用空间越来越小,这种现象称之为内存泄漏。
int main()
{
int n = 5;
int *p = (int*)malloc(n * sizeof(int));
free(p);
system("pause");
return 0;
}
- 对p指针所指向的堆空间进行释放。