zoukankan      html  css  js  c++  java
  • C/C++(内存管理)

    内存管理

    进程空间

    源程序:源代码
    程序(可执行文件):有源程序编译后的文件
    进程:时间概念,可执行文件被拉起到结束的这段过程。进程可以被拉起多个。
    进程空间:可执行文件被拉起,在内存中的分布情况。
    进程空间的分布:

    stack
    heap
    data
    >未初始化
    >初始化
    text
    

    32位机最大寻址3G,
    重点栈,堆

    栈:auto修饰的变量,谁调谁用,用完即消。不需要人工干预。(入栈与出栈的关系),栈溢出。主要用于数据的交换,为不是适用于大空间的申请使用(大数据的申请用堆)

    。大小不超过10M,避免大量的递归。
    发展方向:由高到低先定义的在高位上,后申明的在低位上。

    堆:可以存放任意类型的数据类型,但需要自己申请使用与释放。

    申请:malloc();
    释放:free();
    大小:大空间。
    发展方向:由低到高

    char * p = (char*)molloc(1024*1024*1024);//加内存可解决
    strcpy(p,"adbksj");
    printf("sjdkjfk");
    free(p);
    

    申请mallloc以字节为大小

    基本类型的申请

    int * p = (int*)malloc(1*sizeof(int));//申请int类型的4个字节的大小
    *p = 100;//初始化
    printf("*p = %d
    ",*p);//100
    

    构造类型--数组的申请:
    申请和初始化的最小单位均是字节
    memset(p,0,sizeof(int))初始化

    int arr[10];
    int *p = (int*)malloc(10*sizeof(int));
    memset(p,0,10*sizeof(int));//初始化,p:首地址,0:初始化元素,后面是大小
    for(int i = 0;i < 10;i++) {
        printf("%d
    ",p[i]);//不知道的值,不能使用*p++
    }
    free(p);
    

    calloc()

    int *p = (int *)calloc(10,sizeof(int));//10个4个单元的大小
    for(int i = 0;i < 10;i++) {
        printf("%d
    ",p[i]);//自动初始化了
    }
    

    realloc()扩容

    char * pa = (char*)malloc(10);
    strcpy(pa,"1234567890abcdef");//实际数据大于了申请的空间,这时候使用realloc();
    
    
    char *pa = (char*)malloc(10);
    char *newPa;
    newPa = realloc(pa,20);
    strcpy(newPa,"1234567890abcdef");
    //newPa与pa有时候会不一样
    free(newPa);
    

    或者

    char *pa = (char*)malloc(10);
    pa = realloc(pa,20);
    strcpy(pa,"1234567890abcdef");
    //newPa与pa有时候会不一样
    free(pa);
    

    realloc()有两种情况,一种是空间不足在后买你继续扩充,另一种是开辟的空间不足,重新开辟足够的空间,把数据复制过去。

    应用模型

    #include<stdio.h>
    #include<stdlib.h>
    int main() {
        int *pa;
        int len;
        printf("please new len:");
        scanf("%d",&len);
    
        pa = (int*)malloc(len*sizeof(int));
        int oldlen = len; 
        for(int i = 0;i<len;i++) {
            pa[i] = 100+i;
            printf("%d
    ",pa[i]);
        }
        printf("please large len:");
        scanf("%d",&len);
        pa = (int*)realloc(pa,len*sizeof(int));
        for(int i = 0;i<len;i++) {
            if(oldlen <= i)
                pa[i] = 200+i;
            printf("%d
    ",pa[i]);
        }
        printf("please small large len:");
        scanf("%d",&len);
        pa = (int*)realloc(pa,len*sizeof(int));
        for(int i = 0;i<len;i++) {
            printf("%d
    ",pa[i]);
        }
        free(pa);
    
        return 0;
    }
    

    常见问题解析

    错误模型一:在服务器模型中,常用到大循环,在大循环中未释放原有空间,重新申请新空间,造成原有空间内存泄漏。

    while(1) {
        char *pa = (char*)malloc(100);
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        printf("ooooooooooooo
    ");
        pa = (char*)malloc(100);//前面申请之后没有释放,重新申请
        //第一次申请,没有释放,在内存中占有空间,第二次给同一变量再次申请,前一次的空间没有释放。同样占有内存空间。释放要配对使用。两次使用free();也会挂机。malloc多余free会挂机,free对于malloc也会挂机。
    }
    

    置空与判空

    对内存使用的逻辑:申请,判空,使用,释放,常见错误:释放以后未置空为NULL再次做判空使用或者释放以后继续菲方使用。

    char *pc = (char*)malloc(100);//申请
    if(pc == NULL) {
        printf("error
    ");//内存里已经没有空间了
        exit(-1);
    }
    strcpy(px,"afakjfklajflkfja");//使用
    free(pc);//释放
    pc = NULL;//置空
    

    谁申请谁释放,防止多次释放

    void func(char*p) {
        printf("%s
    ",p);
        free(p);
        p = NULL;
    }
    int main() {
        char *p = (char*)malloc(100);
        if(NULL == p) {
            exit(-1);
        }
        strcpy(p,"adajsfkljlk");
        func(p);
        free(p);
        p = NULL;
    //会挂机,func中无需释放,谁申请谁释放
    
        return 0;
    }
    

    开放的地址空间

    void foo() {
        printf("p = %s
    ",p);
    }
    void func() {
        printf("p = %s
    ",p);
    }
    int main() {
        char *p = (char*)malloc(100);
        strcpy(p,"afkajfklj");
        func(p);
        foo(p);
    
        return 0;
    }
    //p属于同一个变量,但是属于不同空间。p地址在不同的作用域中是共同开放的。
    

    堆与栈空间的返回

    栈空间不可以返回,堆空间可以返回。
    1.只可以返回
    2.地址也可以返回,返回来的地址不要去使用
    3.谁用谁开,用完即消,不可以返回----栈
    4.堆上的空间是可以返回的

    int func() {
        int a = 500;
        return a;
    }
    int* foo() {
        int a = 500;
        /*
        printf("&a = %p
    ",pa);windows下不行
        */
        int *pa = &a;
        printf("&a = %p
    ",pa);
    
        return pa;
    }
    int *func2() {//谁用谁开,用完即消,不可以返回----栈
        int arr[100];
        return arr;
    }
    int main() {
        int a = func();//可以返回
        printf("a = %d
    ",a);
    
        int *pa = foo();//地址可以返回,空间消失了。
        printf("pa = %p
    ",pa);
        return 0;
    }
    

    堆的返回

    char * getFormatMem(int size,char content) {
        char *p = (char*)malloc(size*sizeof(char));
        if(NULL == p) 
            exit(-1);
        memset(p,content,size*sizeof(char)-1);
        p[size*sizeof(char)-1] = '';
    
        return p;
    }
    int main() {
        char *p = getFormatMem(100,'a');//包装好的申请
        printf("p = %s
    ",p);
        free(p);//释放,
    
        return 0;
    }
    
  • 相关阅读:
    爱情五十三课,爱情银行
    [技术][JavaScript] <<JQuery 实战(Jquery in Action)>> Bear Bibeault & Yehuda Katz(美)
    [生活][健康] <<点食成金>> 范志红
    专一不是一辈子只喜欢一个人,是喜欢一个人的时候一心一意。
    【生活智慧】001.追求实在的东西
    【生活智慧】002.以上帝的"特选子民"自居
    【生活智慧】003.不能为了一顿鸡鸭鱼肉而让其他日子挨饿
    爱情五十四课,最需要的一刻
    爱情五十课,牵手的力量
    爱情五十五课,选择可以承担的
  • 原文地址:https://www.cnblogs.com/intelwisd/p/8326020.html
Copyright © 2011-2022 走看看