本文为数据结构打下基础
备注:数据结构需要掌握指针,结构体和动态内存管理
目录
1.内存开辟的方式
01.创建变量
int a = 0;
一次性开辟一块空间(在这里为4字节)
02.创建数组
int arr[10] = { 0 };
一次性开辟一块连续的空间(在这里为4*10==4字节)
但有局限
1.空间开辟的大小是固定的
2.数组空间一旦确定了大小不能调整
为了解决上方的局限,C语言引入了动态内存开辟的函数malloc,free,calloc,realloc来进行动态内存分配
2.malloc函数
malloc:memory allocation
cplusplus网翻译
函数
malloc
void* malloc (size_t size);
分配内存块
分配以字节为单位的内存块,返回一个指向内存块起点的指针
新分配的内存块的内容不会被初始化,保留不确定的值
如果大小(size)为0,返回值依靠特定的库来实现,它可能是也可能不是一个空指针(即不确定是什么类型的指针,因为C标准没有定义),但返回的指针不应被解引用
参数
size:以字节为单位的内存块的大小
size_t是无符号整型
返回值
成功时,指向内存块的指针被函数分配
指针的类型总为void*,它可以被转换为所需的数据指针类型以便解引用
如果函数不能为请求的内存块分配,则返回一个空指针
提炼要点
1.使用前要加#include <stdlib.h>
2.接受返回值时,可能需要强制类型转换(malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定)
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(5);//开辟5个字节的空间
return 0;
}
因为p是int*类型,因此返回值被强制类型转换为int*型
3.如果开辟内存成功,则返回一个指向开辟好空间的指针
4.如果开辟失败,则返回一个空指针,因此malloc函数的返回值一定要做检查
检查方法:
if (p == NULL)
{
printf("返回空指针");
return 1;//错误返回
}
else
{
//使用空间
}
养成良好习惯,判断是否为空指针
5.如果参数size 为0,行为C标准是未定义malloc函数的行为的,取决于编译器
回忆变量存储的三个地区:4.【C语言】初识常量与变量
操作内存空间
通过对指针的解引用来为开辟的内存空间存值
01.开辟内存空间成功
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(5);
if (p != NULL)
{
*p = 1;
printf("%d", *p);
return 0;
}
else
{
perror("malloc");
return 1;
}
}
将*p处的内存空间按整型(4bytes)赋值为1
x86+debug环境下,打开内存窗口
执行完int* p = (int*)malloc(5);后,输入p
从0x00C45F20开始,5个cd为开辟的内存空间
执行完*p = 1;后,再次查看
由于被强制类型转换为int类型,故执行4 bytes
注:前面要判断p不为空指针(否则显示)
题外话:
如果对int* p = (int*)malloc(5);多换几个数字试试,会发现开辟的内存空间的结尾总是跟着4个fd
这个应该是编译器在分配动态内存时堆区空间被初始化的值
具体原因参见"烫烫烫屯屯屯" 那些事
02.开辟内存空间失败
x86+debug环境下
将上方的代码的int* p = (int*)malloc(5);改为int* p = (int*)malloc(INT_MAX);
注:
2147483647bytes==2097151.999023438KB==2,047.999999046326MB=1.999999999068677GB