11.1 程序内存分配
分区:
栈区(stack):存放非局部变量
堆区(heap):存放malloc()等函数动态分配的数据
全局静态区:存放静态局部变量、全局变量
代码区:存放程序代码
动态内存分配指根据需要向系统申请所需大小的空间,由于未在声明部分定义其为变量或者数组,不通过变量名或者数组名来引这些数据,只能通过指针来引用。
11.2 void 指针(无类型指针)
C99允许定义一个类型为void的指针变量,它可以指向任何类型的数据
1、作用
指针变量必须有类型,否则编译器无法知道如何解读内存块保存的二进制数据。但是,有时候向系统请求内存的时候,还不确定会有什么类型的数据写入内存,需要要先获得内存块,稍后再确定写入的数据类型。
这种情况下就可以使用 void 指针,它只有内存块的地址信息,没有类型信息,等到使用该块内存的时候,再向编译器补充说明,里面的数据类型是什么。
2、特点
①void指针与其他所有类型指针之间是互相转换关系,任一类型的指针都可以转为void指针,而void指针也可以转换为任一类型的指针。
②由于不知道 void 指针指向什么类型的值,所以不能用 * 运算符取出它指向的值(解引用)。
int num = 42;
double pi = 3.14159;
// int 指针转为 void 指针
void *viPtr = # // 隐式类型转换
// double 指针转为 void 指针
void *vdPtr = π // 隐式类型转换
// void 指针转换为 int 指针并解引用
// int *intPtr = viPtr; // 隐式类型转换
int *intPtr = (int *)viPtr; // 显示类型转换
printf("整数值:%d \n", *intPtr);
// void 指针转换为 double 指针并解引用
// double *doublePtr = vdPtr; // 隐式类型转换
double *doublePtr = (double *)vdPtr; // 显式类型转换
printf("浮点数:%f \n", *doublePtr);
// void 指针不能解引用 会报错
// printf("%d", *viPtr);
// printf("%d", *vdPtr);
11.3 内存分配相关函数
1、malloc函数
malloc()函数用于分配一块连续的内存空间
函数原型void *malloc(size_t size);size是要分配的内存块大小,以字节为单位
返回值说明:如果内存分配成功,返回一个void指针,指向新分配的内存块的地址;如果内存分配失败,返回一个空指针(NULL)
int *p;
p = (int *)malloc(sizeof(int));
// 判断是否分配成功
if (p == NULL)
{
printf("内存分配失败\n");
return 1; // 退出程序
}
// 使用解引用赋值并输出
*p = 120;
printf("p指向的地址:%p \n", p);
printf("p指向的值:%d", *p);
// 释放分配的内存
free(p);
2、calloc函数
calloc()函数用于分配内存并将其初始化为零,它在分配内存块时会x自动将内存中的每一个字节都设置为零
函数原型:void *calloc(size_t numElement, size_t sizeOfElement);numElement是要分配的元素的数量,sizeOfElement是每一个元素的大小(以字节为单位)
返回值说明:如果内存分配成功,返回一个 void 指针,指向新分配内存块的地址;如果分配失败(例如内存不足),返回一个空指针(NULL)。
int *p; // 定义整型指针
int n = 5; // 定义数组长度
// 动态分配内存,将地址赋给指针p
p = (int *)calloc(n, sizeof(int));
// 判断是否分配成功
if (p == NULL)
{
printf("内存分配失败\n");
return 1; // 退出程序
}
// 输出数组的元素的值
for (int i = 0; i < n; i++)
{
printf("p[%d]=%d \n", i, p[i]);
}
// 释放分配的内存
free(p);
3、realloc函数
realloc()函数用于重新分配malloc函数或者calloc函数所获得的内存块的大小
函数原型:void *realloc(void *ptr,size_t size);ptr是要重新分配的内存块的指针,size是新的内存块的大小(以字节为单位)
int *b;
// 分配内存
b = malloc(sizeof(int) * 100);
printf("b=%p, size:%zu \n", b, _msize(b));
// 调整内存大小
b = realloc(b, sizeof(int) * 2000);
printf("b=%p, size:%zu \n", b, _msize(b));
// 再次调整内存大小
b = realloc(b, sizeof(int) * 200);
printf("b=%p, size:%zu \n", b, _msize(b));
// 释放内存
free(b);
4、free函数
free() 函数用于释放动态分配的内存,以便将内存返回给操作系统,防止内存泄漏。
函数原型:void free(void *ptr);ptr是指向要释放的内存块的指针,ptr必须是malloc函数或者calloc函数动态分配的内存块地址。
注意:①分配的内存块一旦释放,就不应该再次操作已经释放的地址,也不应该再次使用free释放第二次。②如果忘记调用free函数,会地址无法访问未回收的内存块,构成内存泄漏。

532

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



