看完这篇你还能不懂C语言/C++内存管理?

小微 科技看完这篇你还能不懂C语言/C++内存管理?已关闭评论111字数 2802阅读模式
摘要C 语言内存管理指对系统内存的分配、创建、使用这一系列操作。在内存管理中,由于是操作系统内存,使用不当会造成毕竟麻烦的结果。本文将从系统内存的分配、创建出发,并且使用例子来举例说明...

C 语言内存管理指对系统内存的分配、创立、使用这一系列操作。在内存管理中,因为是操作系统内存,使用不当会造成毕竟麻烦的结果。本文将从系统内存的分配、创立动身,并且使用例子来举例说明内存管理不当会呈现的情况及解决方法。

一、内存文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

在计算机中,每一个利用程序之间的内存是互相独立的,通常情况下利用程序 A 其实不能走访利用程序 B,固然一些特殊技能可以走访,但此文其实不详细进行说明。例如在计算机中,一个视频播放程序与一个阅读器程序,它们的内存其实不能走访,每一个程序所具有的内存是分区进行管理的。文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

在计算机系统中,运行程序 A 将会在内存中开拓程序 A 的内存区域 1,运行程序 B 将会在内存中开拓程序 B 的内存区域 2,内存区域 1 与内存区域 2 之间逻辑分隔。文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

1.1 内存四区文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

在程序 A 开拓的内存区域 1 会被分为几个区域,这就是内存四区,内存四区别为栈区、堆区、数据区与代码区。文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

栈区指的是存储一些临时变量的区域,临时变量包含了局部变量、返回值、参数、返回地址等,当这些变量超越了当前作用域时将会自动弹出。该栈的最大存储是有大小的,该值固定,超过该大小将会造成栈溢出。文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

堆区指的是一个比较大的内存空间,主要用于对动态内存的分配;在程序开发中通常为开发人员进行分配与释放,若在程序收场时都未释放,系统将会自动进行回收。文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

数据区指的是主要寄存全局变量、常量以及静态变量的区域,数据区又可以进行划分,分为全局区与静态区。全局变量与静态变量将会寄存至该区域。文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

代码区就比较好理解了,主要是存储可执行代码,该区域的属性是只读的。文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

1.2 使用代码证实内存四区的底层结构文章源自微观生活(93wg.com)微观生活-https://93wg.com/3815.html

因为栈区与堆区的底层结构比较直观的表现,在此使用代码只演示这两个概念。首先查看代码察看栈区的内存地址分配情况:

39;0&include<stdio.h>
intmain
{

inta=0;
intb=0;
charc=&39;;
staticintd=0;

printf;

printf;
}

运行结果如下:

以上代码中创立了一个变量 d,变量 d 为静态变量,运行代码后从结果上得知,静态变量 d 的地址与一般变量 a、b、c 的地址其实不存在连续,他们两个的内存地址是分开的。那接下来在此建一个全局变量,通过上述内容得知,全局变量与静态变量都应当存储在静态区,代码如下:

39;0&include<stdio.h>
intmain
{
chararr_char[1024*1000000];
arr_char[0]=&39;;
}

以上代码定义了一个字符数组 arr_char,并且设置了大小为 1024*1000000,设置该数据是利便查看大小;随后在数组头部进行赋值。运行结果如下:

这是程序运行犯错,缘由是造成为了栈的溢出。在往常开发中若需要大容量的内存,需要使用堆。

堆并无栈同样的结构,也没有栈同样的先进后出。需要人为的对内存进行分配使用。代码如下:

include<string.h>
include<stdio.h>
include<malloc.h>
intmain{
intn,*p,i;
printf;
scanf;

p=malloc);
if{
printf;
return0;
}else{
printf;
}

memset);//填充0

//查看
for
printf;
printf;
free;
p=NULL;
return0;
}

以上代码中使用了 malloc 创立了一个由用户输入创立指定大小的内存,判断了内存地址是不是创立胜利,且使用了 memset 函数对该内存空间进行了填充值,随后使用 for 循环进行了查看。最后使用了 free 释放了内存,并且将 p 赋值 NULL,这点需要主要,不能使指针指向未知的地址,要置于 NULL;否则在以后的开发者会误以为是个正常的指针,就有可能再通过指针去走访一些操作,然而在这时候该指针已经无用,指向的内存也不知此时被怎么使用,这时候若呈现意外将会造成没法预估的后果,乃至致使系统崩溃,在 malloc 的使用中更需要需要。

2.2 内存泄露与安全使用实例与讲授

内存泄露是指在动态分配的内存中,并无释放内存或者一些缘由造成为了内存没法释放,轻度则造成系统的内存资源挥霍,严重的致使整个系统崩溃等情况的产生。

内存泄露通常比较隐秘,且少许的内存泄露产生不一定会产生没法经受的后果,但因为该过错的累积将会造成总体系统的机能降落或系统崩溃。尤其是在较为大型的系统中,怎么有效的避免内存泄露等问题的呈现变得尤为重要。例如一些长期的程序,若在运行之初有少许的内存泄露的问题发生可能并未出现,但跟着运行时间的增长、系统业务处理的增添将会积累呈现内存泄露这类情况;这时候极大的会造成不可预知的后果,如整个系统的崩溃,酿成的损失将会难以经受。由此避免内存泄露对于底层开发人员来讲尤为重要。

C 程序员在开发进程中,不可防止的面对内存操作的问题,尤其是频繁的申请动态内存时会及其容易造成内存泄露事故的产生。如申请了一块内存空间后,未初始化便读其中的内容、间接申请动态内存但并无进行释放、释放完一块动态申请的内存后继续引用该内存内容;如上所述这类问题都是呈现内存泄露的缘由,常常这些缘由因为过于隐秘在测试时不一定会完整清楚,将会致使在项目上线后的长期运行下,致使灾害性的后果产生。

如下是一个在子函数中进行了内存空间的申请,然而并未对其进行释放:

include<string.h>
include<stdio.h>
include<malloc.h>
intm{
FILE*f;
intkey;
f=fopen;
fscanf;
returnkey;
}

intmain{
m;
return0;
}

以上文件在读取时并无进行 fclose,这时候将会发生过剩的内存,可能一次还好,屡次会增添成倍的内存,可使用循环进行调用,以后在任务管理器中可查看该程序运行时所占的内存大小,代码为:

include<string.h>
include<stdio.h>
include<malloc.h>
intm{
intval=freep[0];
printf;
free;
val=freep[0];
printf;
}

intmain{
int*freep=malloc);
freep[0]=1;
m;
return0;

}

以上代码使用 malloc 申请了一个内存后,传值为 1;在函数中首先使用 val 值接管 freep 的值,将 val 乘 2,以后释放 free,从新赋值给 val,最后使用 val 再次乘 2,此时酿成的结果呈现了极大的扭转,而且最恐怖的是该过错很难发现,隐秘性很强,然而酿成的后顾难以经受。运行结果如下:

三、 new 以及 delete

C++ 中使用 new 以及 delete 从堆中分配以及释放内存,new 以及 delete 是运算符,不是函数,二者成对使用。

new/delete 除了了分配内存以及释放内存(与 malloc/free),还做

以上就是微观生活(93wg.com)关于“看完这篇你还能不懂C语言/C++内存管理?”的详细内容,希望对大家有所帮助!

继续阅读
 
小微
  • 版权声明: 本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们(管理员邮箱:81118366@qq.com),情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!
  • 转载请务必保留本文链接:https://93wg.com/3815.html