C语言_动态内存分配

动态内存分配
一.内存的五个分区

1.栈区  后进先出, 从高到底分配内存

    int a = 2;
    int b = 3;
    printf("栈区: %p\n", &a);
    printf("栈区: %p\n", &b);<span style="font-family: Menlo; background-color: rgb(255, 255, 255);">  </span>

2.堆区

堆区分配内存, 从低到高

堆区的内存由我们自己进行分配和释放    

    int *c = malloc(10);    
    printf("堆区: %p\n", c);<span style="font-family: Menlo; background-color: rgb(255, 255, 255);">    </span>

3.静态区

全局变量和被static修饰的静态变量

静态变量 再一次程序执行过程中, 只分配一次内存

    static int d = 5;    
    printf("静态: %p\n", &d);

4.常量区

内存是只读的, 不可修改

    char *ss ="李四";    
    char *e = "zhangsan";    
    printf("常量: %p\n", e);

5.代码区

程序执行的代码都保存在代码区

void testMemory()
{
    printf("代码区");
}
    printf("代码: %p\n", testMemory); 


当程序执行完毕. 全释放掉 常量区和静态区的内存

    

二.内存分配的相关函数


    1.malloc函数

    

     将堆区内存分配4个字节给一个int型的指针

     返回值 void * 代表任意指针

     参数; 分配的内存大小

     考虑到平台不同, 可以用sizeof(char)来确定1个字节

    int *p= malloc(sizeof(char) * 4);

     使用:

    *p = 4;

     在堆区分配8个字节

    char *pp = malloc(sizeof(char) * 8) ;

  

     malloc 对内存的分配不负责清空内容

     str进行的操作和之前的指针操作一致, 比如可以进行字符窜拷贝

    strcpystr(pp, "xiansen");
    printf("%s\n", pp);

     在堆区分配int类型的数据

    int *ppp = malloc(sizeof(int) * 5);

     结构体一样

    Student *stu = malloc(sizeof(Student) * 3);


    

     对分配的内存释放    

     无返回值, 有一个参数, 填任意类型的指针

     释放内存的时候, 只是对内存标记为可用, 并没有对内存进行清空

    free(stu);
    free(pp);
    free(p);
    free(ppp);
    free(c);


     练习:有一字符串,其中包含数字,提取其中的数字.要求动态分配内存保存

 // 定义变量来保存数字的个数
    int count = 0;
    // 定义一个字符串
    char array[] = "1asd34f6asd4f3as1d";
    char *p = array;
    // 循环条件
    while (*p != '\0') {
        if (*p <= '9' && *p >= '0') {
            count++;
        }
        // 每次循环都让指针向下移位
        p++;
    }
    // 分配空间
    char * pp = malloc(sizeof(char) * count + 1);
    // 指针归位
    p = array;
    // 循环遍历
    while (*p != '\0') {
        if (*p <= '9' && *p >= '0') {
            *pp = *p;
            pp++;
        }
        // 在末尾添加'\0'
        if(*(p + 1) == '\0')
        {
            *pp = '\0';
        }
        // 每次循环都让指针向下移位
        p++;
    }
    // 指针归位
    pp = pp - count;
    // 打印
    printf("%s", pp);
    
    free(pp);

   

     练习2:输入3个学员的姓名,动态分配内存保存学员姓名,并在最后输出    

    // 存储输入的内容
    char *name[3] = {0};
    char temp[50] = {0};
    for (int i = 0; i < 3; i++) {
        scanf("%s", temp);
        // 根据输入文字的长度计算分配的内存
        name[i] = malloc(sizeof(char) * strlen(temp) + 1);
        strcpy(name[i], temp);
    }
    // 输出
    for (int i = 0; i < 3; i++) {
        printf("%s\n", name[i]);
    }
    // 释放
    for (int i = 0; i < 3; i++) {
        free(name[i]);
    }

    3.其他的内存管理函数

     calloc

     malloc一样, 区别在于在分配内存的时候清空所有内容, 在效率上略低

     参数1: 分配多少个内存,

     参数2: 每一个内存有多大

    char *str = calloc(2, sizeof(char));

     

     realloc

     重新分配内存大小

     参数1: 给谁分配

     参数2: 重新分配的大小

    str = realloc(str, 100);

  

    

 三.内存操作函数

    

     1.初始化内存    

      参数1: 初始化谁

      参数2: 初始化的值

      参数3: 初始化多少个字节

    str = memset(str, 65, 13);    
    printf("%s\n", str);

  

     2.内存拷贝函数

      参数1: 拷贝到谁

      参数2: 从谁拷贝(source)

      参数3: 拷贝多少字节 

 

     跟字符串拷贝函数的区别; 字符串拷贝只能够拷贝字符串, 内存拷贝可以拷贝任何内容

    memcpy(str + 1,"iii" , 3);
    printf("%s\n", str);


     3.内存比较    

      参数1和参数2: 要比较两块内存

      参数3: 比较多少字节

      返回值: 如果两个内存完全一样, 返回0, 如果不一样, 就把不一样的内存内容取差值返回

   int result = memcmp(str, "aaa", 3);    
   printf("%d", result);

     练习:定义两个整型指针,分别用malloccalloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范 1-3,赋值后用memcmp比较两个数组。如果相同打印Good!否则 打印Failed...    

    int *p = malloc(sizeof(int) * 3);    
    int *pp = calloc(3, sizeof(int));    
    memset(p, 0, 12);    
    for (int i = 0; i < 3; i++) {
        *(p + i) = arc4random() % 3 + 1;
        *(pp + i) = arc4random() % 3 + 1;
    }    
    if (memcmp(pp, p, 12) != 0) {
        printf("Good");
    } else {    
        printf("Failed");
    }    
    free(p);
    free(pp);








   











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值