小甲鱼 P37 38 动态内存管理1 2
下面的库函数包含在stdlib.h
malloc:申请动态内存空间
free:释放动态内存空间
calloc:申请并初始化一系列内存空间
realloc:重新分配内存空间
malloc
函数原型:void *malloc(size_t size);(void类型可以被转换成任何一种类型)
malloc函数向系统申请分配size个字节的内存空间,并返回一个指向这块空间的指针。如果函数调用失败,返回值是NULL。
free
函数原型:void free(void *ptr);
free函数释放ptr参数指向的内存空间。该内存空间必须是由malloc、calloc和realloc函数申请的。
PS:该函数不会修改ptr参数的值,所以调用它仍然指向原来的地方。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
//malloc申请的空间位于内存的堆
ptr = (int *)malloc(sizeof(int));//malloc返回类型为void *
if (ptr == NULL)//内存不够用返回失败,则NULL
{
printf("分配内存失败 !\n");
exit(1);//异常退出
}
printf("请输入一个整数:");
scanf("%d", ptr);
printf("你输入的整数是;%d\n", *ptr);
free(ptr);//如果不主动释放堆上的内存资源,永远的存在,知道程序关闭。造成内存泄漏
printf("你输入的整数是;%d\n", *ptr);
return 0;
}
结果:
malloc可以申请一块任意尺寸的内存空间(由于申请的空间是连续的,所以使用数组来进行索引)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr = NULL;
int num, i;
printf("请输入待录入整数的个数:");
scanf("%d", &num);
ptr = (int *)malloc(num * sizeof(int));
for (i = 0; i < num; i++)
{
printf("请录入第%d个整数:", i+1);
scanf("%d", &ptr[i]);//相当于指针数组,用数组的方式索引ptr
}
printf("你录入的整数是:");
for (i = 0; i < num; i++)
{
printf("%d ", ptr[i]);
}
putchar('\n');
free(ptr);
}
初始化内存空间
以mem开头的函数,包含在string.h这个头文件中
memset:使用一个常量字节填充内存空间
memcpy():拷贝内存空间
返回值:void *
#include <stdio.h>
#include <stdlib.h>
#include <string.h>//memset
#define N 10
int main(void)
{
int *ptr= NULL;
int i;
//连续的内存块,通常用数组来索引
ptr = (int *)malloc(N * sizeof(int));
if (ptr == NULL)
{
exit(1);
}
memset(ptr, 0, N * sizeof(int));//初始化
for (i = 0; i < N; i++)
{
printf("%d ", ptr[i]);//连续的内存块,用数组的方式进行索引
}
putchar('\n');
free(ptr);
return 0;
}
calloc
函数原型:
void *calloc(size_t nmemb, size_t size);
calloc函数在内存中动态申请nmemb个长度为size的连续内存空间(即申请的总空间尺寸为nmemb * size),这些内存空间全部被初始化为0
calloc函数和malloc函数的一个重要区别是:calloc函数在申请完内存后,自动初始化该内存空间为零
下面两种写法是等价的:
//calloc()分配内存空间并初始化
int *ptr = (int *)calloc(8, sizeof(int));
//malloc()分配内存空间,并用memset()初始化
int *ptr = (int *)malloc(8 * sizeof(int));
memset(ptr, 0, 8 * sizeof(int));
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int *ptr1 = NULL;
int *ptr2 = NULL;
//第一次申请的内存空间
ptr1 = (int *)malloc(10 * sizeof(int));
//进行若干操作之后发现ptr1申请的内存空间竟然不够用!!!
//第二次申请的内存空间
ptr2 = (int *)malloc(20 * sizeof(int));
//将ptr1的数据拷贝到ptr2中
memcpy(ptr2, ptr1, 10);//参数:目标,源,长度
free(ptr1);
//对ptr2申请的内存空间进行若干操作...
free(ptr2);
return 0;
}
realloc 重新分配内存空间
函数原型:
void *realloc(void *ptr, size_t size);
PS:
1、如果ptr参数为NULL,那么调用该函数相当于调用malloc(size)
2、如果size参数为0,并且ptr参数不为NULL,那么调用该函数就相当于调用free(ptr)
3、除非ptr参数为NULL,否则ptr的值必须由先前调用malloc、calloc或realloc函数返回
使用realloc来申请内存空间,让用户一直输入一个整数,根据用户每输入一个整数,就新增加一个整形的空间,直到用户输入-1,表示输入结束。把所有的输入打印出来。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, num;
int count = 0;
int *ptr = NULL;//这里必须初始化为NULL,相当于malloc(size)
do
{
printf("请输入一个整数(输入-1表示结束):");
scanf("%d", &num);
count++;
//第一次ptr=NULL,相当于malloc(size)
ptr = (int *)realloc(ptr, count * sizeof(int));//重新分配,相当于指针数组
if (ptr == NULL)
{
exit(1);
}
ptr[count-1]= num;//保存在堆里
}while (num != -1);
printf("输入的整数分别是:");
for (i = 0; i < count; i++)
{
printf("%d ", ptr[i]);
}
putchar('\n');
free(ptr);
return 0;
}