服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言 动态内存管理全面解析

C语言 动态内存管理全面解析

2022-09-20 21:05i跑跑 C/C++

动态内存是相对静态内存而言的。所谓动态和静态就是指内存的分配方式。动态内存是指在堆上分配的内存,而静态内存是指在栈上分配的内存,本文带你深入探究C语言中动态内存的管理

1. 为什么存在动态内存分配

*动态内存开辟在堆区*

我们已经掌握的开辟内存方式是类型直接定义变量,开辟的内存是固定的,像:

int a=20;  //在栈空间上开辟四个字节

还有数组,我们可以指定开辟空间的大小,像:

char arr[10] = {0};  ///在栈空间上开辟10个字节的连续空间

但在程序运行时,很多时候我们会遇到内存不够或者内存过多引起的浪费问题,那么有没有那种使用多少内存开辟多少内存的方法?这就是本篇文章要介绍的动态内存。

 

2. 动态内存函数的介绍

 

2.1 malloc和free

malloc和free都声明在 stdlib.h 头文件中

void* malloc (size_t size);
//向内存申请一块连续可用的空间,并返回指向这块空间的指针

如果开辟成功,则返回一个指向开辟好空间的指针。 如果开辟失败,则返回一个NULL指针。 返回值的类型是 void* ,malloc函数并不知道开辟空间的类型,在使用的时候自己来决定。

void free (void* ptr);
//free函数用来释放动态开辟的内存

如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。

如果参数 ptr 是NULL指针,则函数什么事都不做。

举例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
	//开辟10个整型空间
	int* p = (int*)malloc(40);
	if (NULL==p)
	{
		printf("%s
",strerror(errno));  //判断开辟失败的原因
		return 0;
	}
	//使用
 
	//释放
	free(p);  //将空间还给系统,但是里面的内容没有改变,还可以通过p来找到地址
	p = NULL;  //因此要将地址置为空指针
	return 0;
}

 

2.2 calloc 

void* calloc (size_t num, size_t size);
//num为元素个数,size为每个元素的大小

注:与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0

C语言 动态内存管理全面解析

当用calloc来开辟10个整型空间时

int* p = (int*)calloc(10,sizeof(int));

C语言 动态内存管理全面解析

 

2.3 realloc

void* realloc (void* ptr, size_t size);
//ptr 是要调整的内存地址     size 调整之后新大小
//返回值为调整之后的内存起始位置

realloc在调整内存空间的是存在两种情况:

1.当原地址后有足够的空间时,可以接着原地址连续开辟空间,最后返回起始地址。

2.当原地址后空间不足以开辟我们所需要的空间时,那么realloc会自动寻找一块足以存放我们需要的的空间,并将原地址的内容复制到新空间中,释放掉原地址中的内容,返回开辟出空间的初始地址。

C语言 动态内存管理全面解析

我们可以先判断是否开辟成功,再将地址赋予p

C语言 动态内存管理全面解析

 

3. 常见的动态内存错误

 

3.1 对NULL指针的解引用操作

开辟动态内存时,一定要注意对返回空指针的函数要进行判断,防止对空指针进行解引用,以免程序出现问题。

 

3.2 对动态开辟空间的越界访问

 int *p = (int *)malloc(10*sizeof(int));   //开辟内存
 
 if(NULL == p)    //判断是否开辟成功
 {
 exit(EXIT_FAILURE);
 }
 
 int i=0;
 for(i=0; i<=10; i++)
 {
 *(p+i) = i;//当i是10的时候越界访问
 }
 free(p);

C语言 动态内存管理全面解析

这块可以像理解数组一样,不能访问下标为10的地址,会造成越界访问。

 

3.3 对非动态开辟内存使用free释放

void test()
{
	int a = 10;
	int *p = &a;
	free(p);
}
 
 
int main()
{
	test();
	return 0;
}

C语言 动态内存管理全面解析

不是动态内存开辟的空间内存不在堆区,没必要用free释放,在栈区开辟的空间在出了作用域后会自动还给系统,没有必要,也不允许用free进行释放。

 

3.4 使用free释放一块动态开辟内存的一部分

void test()
{
 int *p = (int *)malloc(100);
 p++;
 free(p);//p不再指向动态内存的起始位置
}

C语言 动态内存管理全面解析

 不支持释放一部分内存,这样的写法不支持不可取。只能从动态内存开辟的起始位置来进行释放。

 

3.5 对同一块动态内存多次释放

void test()
{
 int *p = (int *)malloc(100);
 free(p);
 free(p);//重复释放
}

重复释放也会报错

C语言 动态内存管理全面解析

当p第一次释放后,将p=NULL,再次释放的话就不会有问题;写代码是要避免重复释放的情况,同时要记住每次释放完之后都要将地址置为空指针。

若忘记释放开辟的空间,就会造成内存泄漏的问题(在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费)

到此这篇关于C语言 动态内存管理深入理解的文章就介绍到这了,更多相关C语言 动态内存管理内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_53316121/article/details/122748819

延伸 · 阅读

精彩推荐
  • C/C++Visual Studio2000系列版本安装OpenGL的图文教程

    Visual Studio2000系列版本安装OpenGL的图文教程

    这篇文章主要介绍了Visual Studio2000系列版本安装OpenGL的图文教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴...

    界内嘻哈10732021-08-31
  • C/C++C语言使用广度优先搜索算法解决迷宫问题(队列)

    C语言使用广度优先搜索算法解决迷宫问题(队列)

    这篇文章主要介绍了C语言使用广度优先搜索算法解决迷宫问题,结合迷宫问题分析了C语言队列广度优先搜索算法的相关使用技巧,需要的朋友可以参考下...

    e42108345810422021-06-01
  • C/C++全局静态存储区、堆区和栈区深入剖析

    全局静态存储区、堆区和栈区深入剖析

    在C++中,内存可分为系统数据区,自由存储区,文本区,const数据区,全局静态区,堆区和栈区...

    C++教程网2082020-11-09
  • C/C++C语言实现外卖管理系统

    C语言实现外卖管理系统

    这篇文章主要为大家详细介绍了C语言实现外卖管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Dolary6952021-08-06
  • C/C++gdb调试命令的使用及总结

    gdb调试命令的使用及总结

    gdb是一个在UNIX环境下的命令行调试工具。如果需要使用gdb调试程序,请在gcc时加上-g选项。下面的命令部分是简化版,比如使用l代替list等等...

    C++教程网2542020-11-23
  • C/C++VC++实现程序开机启动运行的方法

    VC++实现程序开机启动运行的方法

    这篇文章主要介绍了VC++实现程序开机启动运行的方法,很实用的功能,需要的朋友可以参考下...

    C++教程网7852021-01-25
  • C/C++C++之父访谈录:我也没想到C ++会这么成功!

    C++之父访谈录:我也没想到C ++会这么成功!

    C ++的起源可以追溯到1979年,当时Bjarne Stroustrup着手开发这种语言时,它还被称为“ C with Classes”。这门编程语言设计的初衷,是对C编程语言进行改进,增...

    C语言与C++编程3052020-11-24
  • C/C++Qt地图自适应拉伸的实现示例

    Qt地图自适应拉伸的实现示例

    最近需要写一个程序,要是让qt到程序自适应,本文主要介绍了Qt地图自适应拉伸的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感...

    feiyangqingyun10652022-07-20