当前位置:网站首页>C语言进阶篇 五.动态内存管理
C语言进阶篇 五.动态内存管理
2022-07-24 05:16:00 【且随疾风前行->】
目录
为什么存在动态内存分配
在创建变量时需要为变量分配内存空间,例如:
int a=10;
char arr[20]={0};上述方式是分别在栈区上为a变量开辟了4个字节的空间和在栈上开辟了20个字节的连续空间,上述开辟空间大小取决于变量的类型,数组开辟空间时的大小也是取决于元素个数和元素的类型,在一些应用场景下不能灵活地分配空间,而且局部变量的生命周期有限,出了作用域就销毁了。
为了更合理地分配内存,引入了动态内存分配,如其名,可以按需动态地开辟内存空间。
四大区:
动态内存分配函数
C语言提供了一些动态内存分配函数可以在堆区开辟内存空间。
void* malloc (size_t size);//size_t 是一个unsigned int 类型
这个函数可以开辟size个字节的空间,并返回一个指向内存起始地址的指针,新开辟的内存空间是未被初始化的,存储的是不确定的值。
如果size为0,函数的返回值取决于函数是如何实现的,这时返回值不能解引用(通常是空指针)。
这个函数也可能申请空间失败,这时返回的是空指针,故通常在使用函数malloc申请一块内存空间后要判断返回值是否为空。
堆区空间使用完就需要被释放,否则程序在运行时就存在内存泄漏(程序正常结束时空间会被操作系统自动释放)
这时要搭配另一个函数使用:
void free (void* ptr);
它的作用就是释放动态内存分配的空间,如果指向的空间不是动态开辟的,行为未定义。
如果ptr为空指针,该函数啥也不做。
注意:该函数并不会改变ptr指针,因此,该指针还指向原来的空间(需要手动置空,否则ptr是野指针)
另外两个开辟动态内存的函数:
void* calloc (size_t num, size_t size);
calloc函数会动态开辟num个元素的数组的空间,每个元素空间大小是size字节,并且每个元素被初始化为0,故共开辟了num*size个字节的空间。
如果size为0,该函数不一定返回空指针(取决于库的实现),故返回值不可解引用。
void* realloc (void* ptr, size_t size);
改变ptr指向的动态开辟内存的大小,新开辟的空间大小是过去大小和size的较小值,如果size更大,新开辟的内存空间的内容不确定。
如果ptr是空指针,这个函数的作用同malloc的一样。
(C90标准下,size为0是函数作用同free,会返回空指针,C99标准下不一定返回空指针)
如果空间开辟失败会返回空指针,原来的ptr指向的内存空间不会被释放(原来空间有效,不会被改变)。
常见的动态内存错误
1.解引用空指针
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}2.越界访问
void test()
{
int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
exit(-1);
}
*(p+10) = 11;//越界访问
free(p);
}3.free释放非动态开辟的内存
void test()
{
int a = 10;
int *p = &a;
free(p);//错误
}4.free释放动态开辟内存的一部分
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存开辟的空间的起始位置
}5,用free多次释放动态开辟的内存
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放
}6.忘记释放动态开辟的内存
void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();//未释放开辟的动态内存空间
}柔性数组
C99 中,结构体中的最后一个元素允许是未知大小的数组,这就叫做 柔性数组 成员。
例如:
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
为柔性数组a开辟的4*100个字节的空间,这样开辟的内存是连续的
支持随机访问,访问速度快,内存碎片少。
p->i = 100;
for(int i = 0; i<100; i++) {
p->a[i] = i;
}
free(p);
边栏推荐
- C table data De duplication
- Image painting for irregular holes using partial revolutions paper notes
- Codeforce:d2. remove the substring (hard version) [greedy string + subsequence]
- 【Pytorch】nn.Module
- Optional consistency
- Reading excerpts from Liu run's "bottom logic"
- The network NN can calculate the NTCP provided by the host system
- 【sklearn】tree.DecisionTreeClassifier
- AttributeError: ‘NoneType‘ object has no attribute ‘shape‘
- Scikit learn -- steps of machine learning application development
猜你喜欢

DHCP principle and configuration

Tips for using BeanShell built-in variable prev

JDBC encapsulates a parent class to reduce code duplication

Use of fiddler packet capturing tool

T 6-10

Introduction to 51 single chip microcomputer (dedicated to the most understandable article for beginners)
![Knowledge record of College Physics C in advance in summer [update]](/img/c4/76b669c3229a365a5e2567f7fb824e.png)
Knowledge record of College Physics C in advance in summer [update]

Theoretical basis of machine learning

SSH service

T 1-5
随机推荐
【sklearn】数据预处理
【常用技巧】
熊市抄底指南
The network NN can calculate the NTCP provided by the host system
。 Single type digital sensing is an application 0 Up address is at the factory
Recursive cascade network: medical image registration based on unsupervised learning
MS simulated written test
Hcip day 3 - mGRE experiment
Generics and annotations
JMeter FAQs
un7.23:如何在linix上安装MySQL?
anaconda常用命令的整理
【sklearn】RF 交叉验证 袋外数据 参数学习曲线 网格搜索
PXE efficient batch network installation
Codeforce:d2. remove the substring (hard version) [greedy string + subsequence]
NumPy 统计相关函数示例教程
【Pytorch】Dataset_DataLoader
Execution sequence of finally and return
Pointer learning diary (IV) use structure and pointer (linked list)
CentOS 7安装Mysql5.6.37