首页 > 编程语言 > 详细

c语言内存管理

时间:2021-03-18 10:04:40      阅读:28      评论:0      收藏:0      [点我收藏+]

内容概要

  一、动态内存管理

  二、c语言内存布局

  三、思考题

 

1、动态内存管理

  c语言中的变量是要事先定义好才能使用,在程序执行过程中动态创建是不允许的。但是在C99后已经实现了变量动态创建

    如果想要动态创建变量,可以使用库stdlib.h下提供的功能

      -malloc(参数一)

        参数一:要开辟多少字节的内存

        功能:创建一个动态的内存,这个内存位于堆中

        返回值:返回一个指向这个内存位置的void类型指针

#include <stdio.h>
#include <stdlib.h>

int main(void){
    int *pa;
    pa = (int *)malloc(sizeof(int));  //创建一个int类型大小的内存空间
    *pa = 120;
    
    printf("%d   %p\n", *pa, pa);
    free(pa);  //释放pa指向的内存,这个内存应该有malloc,calloc或者realloc开辟的内存(存放在堆中)
    return 0;
}

        需要注意的是malloc开辟的空间存放在堆区,这部分内存不会在函数调用结束之后释放,需要程序员指定才会释放

        像是在python使用open()函数之后使用close()向操作系统发出回收文件资源的命令

#include <stdio.h>
#include <stdlib.h>

int main(){
    int *pa;
    while (1){
        pa = (int *)malloc(sizeof(int));
    }
    
    return 0;
}

        把内存搞炸

#include <stdio.h>
#include <stdlib.h>

int main(){
    int *pa;
    while (1){
        pa = (int *)malloc(sizeof(int));
        free(pa);
    }
    
    return 0;
}

        炸不了了

 

        使用malloc也可能调用失败,只是函数会返回NULL指针

 

    像操作数组那样操作返回的指针

#include <stdio.h>
#include <stdlib.h>

int main(){
    
    int n;
    int *pa;
    // 动态创建
    printf("please input how long you want:");
    scanf("%d",&n);
    pa = (int *)malloc(n * sizeof(int));

    // 像数组一样遍历,发现是随机值
    for (int i = 0; i < n; i++){
        printf("%d\n",pa[i]);
    }
    
    // 回收资源
    free(pa);
    return 0;
}

    为"数组"初始化,利用memset函数

        要使用memset函数,需要导入库string.h

        -memset(参数一,参数二,参数三)

          参数一:动态内存指针

          参数二:初始化值

          参数三:动态内存大小

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    int *pa;
    pa = (int *)malloc(8,sizeof(int));
    // 初始化
    memset(pa, 0 ,8 * sizeof(int));
    
    for (int i = 0; i < 8; i++){
        printf("%d\n",pa[i]);
    }
    return 0;
}

 

    切记要使用指针关联动态开辟的内存

#include <stdio.h>
#include <stdlib.h>

int main(){
    int *pa;
    int num = 10;
    pa = (int *)malloc(sizeof(int));
    pa = &num; // 再也找不到指向那个位置的内存地址了
    
    return 0;
}

    同时不要对局部变量使用free

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    int *pa;
    int num = 10;
    pa = (int *)calloc(8,sizeof(int));
    pa = &num;
    free(pa)
    }
    return 0;
}

 

      -calloc(参数一,参数二)

        参数一:存放元素的个数

        参数二:每个元素的长度

        功能:在上面的例子中,会发现遍历未初始化的动态内存,会打印随机的数值。使用calloc函数可以在动态创建内存空间时设置初始值。

        返回值:void类型指针

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    int *pa;
    pa = (int *)calloc(8,sizeof(int));for (int i = 0; i < 8; i++){
        printf("%d\n",pa[i]);
    }
    return 0;
}

        -memcpy拷贝内存空间

        -memove拷贝内存空间

        -memcmp比较内存空间

        -memchr在内存空间中查找一个字符

 

      -realloc(参数一,参数二)

        参数一:要更新的动态内存地址

        参数二:新的内存大小

        功能:更新动态内存的大小

        返回值:void类型的内存地址(这个void地址可能和传入的参数相同,也可能不同)

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    int *pa;
    pa = (int *)calloc(8,sizeof(int));
    printf("before: %p\n",pa);
    pa = (int *)realloc(pa,16 * sizeof(int));
    printf("after: %p\n",pa);  //两次地址应该一样
    
    free(pa);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    int *pa;
    pa = (int *)calloc(8,sizeof(int));
    printf("before: %p\n",pa);
    pa = (int *)realloc(pa,1000 * sizeof(int));
    printf("after: %p\n",pa);  //两次地址应该不一样
    
    free(pa);
    return 0;
}

    如果向realloc函数传入NULL指针,就相当于调用malloc函数

 

    一个根据用户输入创建动态"整形数组"的小练习

#include <stdio.h>
#include <stdlib.h>

int main(){
    int num;
    int count = 0;
    int *pnum = NULL;
    
    while (1){
        printf("please input a number(input -1 end process):");
        scanf("%d",num);

        if (num == -1){
            for (int i = 0; i<count; i++){
                printf("%d\n",pnum[i]);
            }
            break;
        }
        
        count++;
        pnum = (int *)realloc(pnum,count * sizeof(int));
        pnum[count] = num;
    }
}

 

2、c语言内存管理

  c语言不同类型变量内存地址的比较

#include <stdio.h>
#include <stdlib.h>

int global_var_a;
int global_var_b = 1024;

void func(void);

void func(void){
    ;
}

int main(void){
    int local_var1;
    int local_var2 = 111;
    
    static int static_var1;
    static int static_var2 = 512;
    
    char *str1 = "You are right!";
    char *str2 = "hello world";
    
    int *pa = (int *)malloc(sizeof(int));
    
    printf("addr of func is: %p\n", func);
    printf("addr of global_var_a is: %p\n", &global_var_a);
    printf("addr of global_var_b is: %p\n", &global_var_b);
    printf("addr of local_var1 is: %p\n", &local_var1);
    printf("addr of local_var2 is: %p\n", &local_var2);
    printf("addr of static_var1 is: %p\n", &static_var1);
    printf("addr of static_var2 is: %p\n", &static_var2);
    printf("addr of str1 is: %p\n", str1);
    printf("addr of str2 is: %p\n", str2);
    printf("addr of pa is: %p\n", pa);
    
    return 0;
}

 

  内存分段图解

 

 

  使用size命令查看每个分段大小

c语言内存管理

原文:https://www.cnblogs.com/laijianwei/p/14552996.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!