关于内存分区及内存申请详解

内存可分为四个区分别是正文段,数据段,堆区以及栈区。用一个图来形象介绍。

 

 下面我们来一个个详细介绍各个区。

一、正文段或者叫代码段

这个段里面存放的是程序运行时的代码,这些代码在运行时是只读的。

二、数据段

数据段又可以分为下面三个小段

1、未初始化数据段:存储未初始化的静态变量或者全局变量,系统会自动初始化为0;

2、初始化数据段:存储初始化的静态变量或者全局变量;

3常量区:常量,const修饰的静态变量和全局变量。

三、堆区

程序员自己进行管理的,使用时需要申请,使用完成要释放内存。

四、栈区

局部变量,形参,保护现场;栈区不会自动初始化。

上面的都好理解,下面来看一段程序,大家想想下面的变量是在哪个区。


int  g_num = 99;

int main()
{
    static int b;
    const int  a;

    const static int c = 0;
    int *p = &c;

    *p = 10;
    return 0;
}
 

请问g_num、b、a、c等分别在内存的什么位置。答案在最后。大家可以先想想。

下面介绍一下卖脑阔malloc和福瑞free这两个函数。

这两个函数一般是配对使用,我们上面说到的堆区,堆区里面的内存要想使用就得使用malloc进行申请,我目前知道的就只有这个函数可以。malloc负责申请空间,free负责释放空间。可以这样理解,malloc申请空间时在堆区的一块连续的内存做了一个标记,表示这块内存以及被分配,而free则是把这个标记给去掉,告诉系统这块内存没人使用了。

malloc()括号里面是要申请的字节数。一般使用sizeof(类型名)乘上需要的元素个数。而且malloc返回的是一个void指针类型。想要获得相应的类型,需要在malloc前面加上强制转换,记得强转也要带上 “*” 号。毕竟人家可是一个指针类型。

free()括号里面放的是通过malloc获得的空间的首地址,就是接收malloc返回值的那个指针。

可能说起来比较抽象,我们来写一个简单的程序。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *p=NULL;
    p=(int*)malloc(sizeof(int)*2);
    for(int i=0;i<2;i++)
    {
        p[i]=i;
    }
    for(int i=0;i<2;i++)
    {
    printf("%d\n",p[i]);
    }
    free(p);
    return 0;
}

最后打印出来的结果是

0

1

通过程序是不是就很好理解malloc的用法,一定要记得每次使用完malloc后,要使用free进行内存释放不然容易出现内存泄漏的问题。

说到这我们有三个注意事项:

1、注意内存不要越界,即我们申请了3个字节大小的空间,实则使用的3个以上,这里字符串当中最容易出错,就比如我们申请了3个字节的空间

a[3]="abc";

字符串的大小一般是元素个数+1,因为最后还有一个‘\0’;这一点很容易被忽略,一定要注意!!!

2、内存泄漏问题,就是我们刚刚说的,不用的内存空间要及时使用free进行释放。内存泄漏可能会导致程序崩溃以及设备卡顿的情况。

3、内存不要进行二次释放,一个malloc对应一个free就行,不要多次用free进行释放,因为你在第一次free之后,malloc申请的空间的标记就被取消了,系统可能被将那块内存分配给别的东西使用,再进行释放的话容易导致数据丢失。

4、释放完内存后记得要将指针指向NULL;

程序答案:

g_num是放在初始化数据段的,因为他是在int mian()函数上面,属于全局变量,而且被初始化赋值为99;

b是放在未初始化数据段,static修饰的静态整型变量,未进行初始化,系统初始化为0;

a是放在栈区,虽然前面有const,但是他依旧只是一个局部变量;

c很显然就是数据段的常量区,和b有明显的区别,不仅有const修饰而且还有static修饰,被初始化未0,c的值不仅是静态的而且还不能被改变。

好了,大概就这么多,谢谢观看。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值