//函数原型:void* malloc(size_t size) void* 可以转换为任意类型指针
//malloc函数向申请分配size个字节的内存空间,并返回一个指向这块空间的指针(转换后),但不会帮我们初始化空间
//如果函数调用失败,返回值为NULL,若size设为0,返回值也可能是NULL,但不意味着函数调用失败
//如果申请内存后,使用完没有及时释放,容易造成内存泄漏,程序崩溃
//所以malloc和free成对出现
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
//***********malloc和free******************
int* ptr;
int num = 123;
ptr = (int*)malloc(sizeof(int)); //申请内存后void*-->int*
if (ptr == NULL)
{
printf("分配内存失败\n");
}
else
{
printf("请输入一个整数:");
scanf_s("%d", ptr);//scanf不会检查边界,可能会造成数据溢出,
printf("输入的整数是:%d\n", *ptr);
//ptr = # //指向了其他内存,原内存无法释放,导致隐式的内存泄漏,造成程序崩溃
//printf("num:%d\n", *ptr); //
free(ptr); //free函数指向ptr指向的内存空间,该内存空间由malloc,calloc或realloc函数申请
//否则,该函数将导致未定义行为,如果ptr为NULL,则不执行任何操作。
//该函数并不会修改ptr参数的值,调用后它仍然指向原来的地方,只不过变为非法空间,访问不到原来的数据
}
//****************小实验:实现动态录入多个整数***********
int* p = NULL;
int num1;
printf("请输入待录入整数的个数:");
scanf_s("%d", &num1);
p = (int*)malloc(sizeof(int) * num1);
if (p == NULL)
{
printf("内存申请失败");
}
else
{
for (int i = 0; i < num1; i++)
{
printf("请输入第%d个整数:", i + 1);
scanf_s("%d", p + i);
}
printf("你输入的全部整数为:");
for (int i = 0; i < num1; i++)
{
printf("%d ", p[i]);
}
printf("\n");
free(p);
}
//****************其他内存管理函数**************
//以mem开头的函数(返回值为void*),包含于string.h中,与str开头的函数(返回值为字符指针char*)区别开
//处理内存空间用mem开头,处理字符串用str开头
//memset 使用一个常量字节填充内存空间
//memcpy 拷贝内存空间
//memmove 拷贝内存空间
//memcmp 比较内存空间
//memchr 在内存空间搜索一个字符
int* pp = NULL;
pp = (int*)malloc(10 * sizeof(int));
if (pp == NULL)
{
printf("内存申请失败\n");
}
else
{
memset(pp, 0, 10 * sizeof(int)); //申请的这段内存初始化为0
for (int i = 0; i < 10; i++)
{
printf("%d ", pp[i]); //0 0 0 0 0 0 0 0 0 0
}
printf("\n");
free(pp);
}
//void* calloc(size_t nmemb,size_t size);calloc函数在内存中动态申请nmemb个长度为size的连续内存空间
//即申请的内存空间总尺寸为nmemb*size,这段内存空间全部被初始化为0
//与malloc的重要区别是会执行初始化为0
int* p1 = (int*)calloc(8, sizeof(int));
if (p1 == NULL)
{
printf("内存申请失败");
}
else
{
for (int i = 0; i < 8; i++)
{
printf("%d ", p1[i]); //0 0 0 0 0 0 0 0
}
printf("\n");
free(p1);
}
//memcpy实现内存拷贝
int* p2 = NULL;
int* p3 = NULL;
p2 = (int*)malloc(10 * sizeof(int));
if (p2 == NULL)
{
printf("内存申请失败\n");
}
else
{
//p2....
//此处p2一系列操作后,若申请的p2指向的内存不够用
p3 = (int*)malloc(20 * sizeof(int));
if (p3 == NULL)
{
printf("内存申请失败\n");
}
else
{
//将p2的数据拷贝到p3中,并释放p2
memcpy(p3, p2, 10);
free(p2);
//对p3进行操作
//p3....
//释放p3
free(p3);
}
}
//void* realloc(void* ptr,size_t size)实现ptr指向的内存重新分配size大小
//如果新分配的内存空间大小size比原来的大,则原来内存中的数据不会发生改变,否则会导致数据丢失
//如果ptr为NULL,则相当于调用malloc(size)
//如果size为0,且ptr不为NULL,则该函数相当于free(ptr)
//除非ptr参数为NULL,否则ptr的值必须由先前调用malloc,calloc或realloc函数返回的
//*************小实验:将用户输入不断存入内存,-1退出********
int n;
int count = 0;
int* pr = NULL; //必须初始化为NULL,realloc开始调用时相当于malloc
do
{
printf("请输入一个整数,-1表示结束\n");
scanf_s("%d", &n);
count++;
pr = (int*)realloc(pr, count * sizeof(int));
if (pr == NULL)
{
printf("内存申请失败\n");
}
else
{
pr[count - 1] = n; //前面的数据会自动存入新的内存,将最新数据手动存入
}
} while (n != -1);
printf("输入的所有整数为:\n");
for (int i = 0; i < count - 1; i++) //输出所有整数,不包括表示结束的数-1
{
printf("%d ", pr[i]);
}
printf("\n");
free(pr);
return 0;
}
网友评论