C内存管理

内存管理

变量

1.1 变量作用域

1.2 全局变量

出现在括号之外的变量,就是全局变量

extern int age; //有一个变量 类型是int 名字是age,已经在其他文件中定义了,可以直接使用

1.3 auto自动变量

默认的类型

auto int a1 = 0;    //不写auto,C语言默认变量都是auto的  还有signed也是默认的

1.4 register寄存器变量

通常变量在内存当中,如果能把变量放到CPU的寄存器里面,代码的执行效率会很高

register int i = 0; //建议,如果有寄存器空闲,那么这个变量就放到寄存器

int *p = $i ;   //报错,对应一个寄存器变量,是不能取地址操作。寄存器的变量是没有内存地址

1.5 静态变量

只初始化一次,而且程序运行期间,静态变量一直存在。一个代码块内的静态变量只能被代码块内部访问

void mystatic()
{
    static int a = 0;   //只执行一次,变量一直存在
    //int a = 0;    //如果是自动变量,此时总是从0开始的
    printf("a = %d\n",a);
    a++;
}

int main()
{
    for ( int i = 0; i < 10; i++){
        mystatic();
    }
}

一旦全局变量定义为static,就只能在当前定义的文件内有效

1.6 全局函数和静态函数

默认是全局函数,如果在函数前面加了static 表示函数只能在当前文件内部使用

内存四区

int c = 0 //静态区

int main()
{
    static int d = 0;   //变量在静态区
    int a = 0;          //变量在栈区
    int c = 0;          //变量在栈区
    
    return 0;
}
int *geta()
{
    int a = 100;
    return &a;
}//int a从这个地方出栈

int main()
{
    int *p = geta();    //这里得到一个临时栈变量的地址,这个地址在函数geta调用完成之后就无效了,可能出现野指针错误
    *p = 100;           //可能出现错误,一定要注意
    printf("%d\n",*p);
    
    return 0;
}

1.1 代码区

程序被操作系统加载到内存的时候,所有的可执行代码放在代码区,这块内存是不可以在运行期间修改的。

1.2 静态区

存放静态变量和全局变量

1.3 堆区

堆是一个大容器,它的容量要远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成。

1.4 栈区

栈不会很大,一般都是以K为单位的

栈溢出:当栈空间已满,但还往栈内存压变量,这个就叫栈溢出

所有的自动变量,函数的形参都是有编译器自动释放出栈的,都放在栈区的

对于自动变量,什么时候入栈出栈,是不需要程序控制的,有C语言编译器实现

对于一个32位的操作系统,最大管理4G内存,其中1G是给操作系统自己用的,剩下的3G是给用户程序的,一个用户程序理论上可以使用3G的内存空间。

//模拟栈溢出的情况

int main()
{
    //定义一个超大的数组,就会出现栈溢出
    char array[1024 * 1024 * 100] = {0};    //数组在栈区,占100M的空间

    array[0] = 'a'; 
    
    
    return 0;
}


1.5 malloc和free

malloc和free要成对使用。一个内存不能free两次。

#include <stdlib.h>

int main()
{
    //分配内存
    int *p = (int *)malloc(sizeof(int) * 10);//在堆中间申请内存,在堆中申请了10个int大小的空间
    //清空内存
   memset(p, 0, sizeof(int) * 10);    
    //赋值
    int i;
    for(i = 0; i < 10; i++)
    {
        p[i] = i;
    }
    
    
    char *p1 = mallloc(sizeof(char) * 10);//在堆中申请了10个char大小的控件
    
    //释放通过malloc分配的堆内存
    free(p);
    free(p1);
}


//错误,返回栈内存地址,会被释放掉
int *geta()
{
    int a = 10;
    return &a;
}

//合法,可以通过函数的返回值返回一个堆地址,但是一定要记得free
int *geta1()
{
    int *p = malloc(sizeof(int));
    return p;
}

//合法的,静态区的可以得到,但是不能free
int *geta2()
{
    static int a = 0;
    return &a;
}


会崩溃
函数的形参*p跟main函数的*p不是同一个,都在栈区    当前这个函数是值传递
void getheap(int *p){

    p = malloc(sizeof(int) * 10);
    
}

int main()
{
    int *p = NULL;
    getheap(p);
    
    p[0] = 1;
    p[1] = 2;
    
    free(p);
    
    return 0;
}

1.6 堆、栈和内存映射

C/C++要手动释放内存

动态创建数组

int i;
scanf("%d",&i);
int *p = (int *)malloc(sizeof(int) * i);

c语言中,函数的形参是从右往左入栈

1.7 calloc和realloc

操作管理内存的最小单位是 页 不是字节 linux32位的操作系统一般一个内存页就是4K

calloc

//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
int main()
{
    //malloc,分配内存后,内容随机,需要手动清0
    char *p = malloc(sizeof(char)*10);  //分配堆内存,但是内容不知道
    memset(p,0,10);         //清空内存
    
    //calloc,分配后内容已经是清0的
    char *q = calloc(10,sizeof(char)); //分配堆内存,分配10个字节
    
    //都需要free
    free(p);
    free(q);
}

realloc

int main()
{
    //calloc申请内存
    char *p1 = calloc(10 * sizeof(char));
    //realloc,在原有内存基础之上,在堆中间增加连续的内存
    //如果原有内存没有连续空间可扩展,那么会新分配一个控件,将原有内存拷贝到新控件,然后释放原有内存
    //realloc和malloc一样,只分配,不清0  需要手动清0
    char *p2 = realloc(p1,20);      //在p1基础上再分配,总共20个
    
    //释放(此时p1和p2地址是相同的)
    free(p2);
    
    
    //
    char *ppp = realloc(NULL,5); //等同于malloc(5)
    
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容