您的位置:首页 > 编程语言 > C语言/C++

C语言动态内存管理

2020-04-07 12:13 1256 查看

文章目录

  • 二、内存被耗尽
  • 三、野指针
  • 四、应用经验
  • 五、课后作业
  • 六、版权声明

  • 在C语言中,编写程序的时候不能确定内存的大小,希望程序在运行的过程中根据数据量的大小动态的分配内存。动态内存管理,就是指在程序运行过程中动态的申请和释放内存空间。

    C语言允许程序动态管理内存,需要时随时开辟,不需要时随时释放。内存的动态管理是通过调用库函数来实现的,主要有malloc和free函数。

    一、相关的库函数

    1、malloc 函数

    函数的原型:

    void *malloc(unsigned int size);

    malloc的作用是向系统申请一块大小为size的连续内存空间,如果申请失败,函数返回0,如果申请成功,返回成功分配内存块的起始地址。

    例如:

    malloc(100); // 申请 100 个字节的临时分配域,返回值为其第一个字节的地址

    malloc的返回值的地址的基类型为void,即不指向任何类型的数据,只提供一个地址,程序中需要定义一个指针来指向动态分配的内存地址。

    例如:

    int *pi=malloc(sizeof(int));

    2、free 函数

    函数的原型:

    void free(void *p);

    free的作用是释放指针p指向的动态内存空间,p是调用malloc函数时返回的地址,free函数无返回值。

    例如:

    free(pi);     // 释放指针变量pi指向的已分配的动态空间

    示例(book107.c)

    /*
    * 程序名:book107.c,此程序用于演示C程序动态内存管理。
    * 作者:C语言技术网(www.freecplus.net) 日期:20190525
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct st_girl  // 超女结构体
    {
    char name[50];     // 姓名
    int  age;          // 年龄
    };
    
    int main(int argc,char *argv[])
    {
    int    *pi=malloc(sizeof(int));    // 分配int类型大小的内存
    long   *pl=malloc(sizeof(long));   // 分配long类型大小的内存
    double *pd=malloc(sizeof(double)); // 分配double类型大小的内存
    char   *pc=malloc(101);            // 分配101字节的内存,可存放100个字符的字符串
    struct st_girl *pst=malloc(sizeof(struct st_girl)); // 分配struct st_girl结构体大小的内存
    
    // 以下代码是像普通指针和变量一样使用动态分配的内存
    *pi=10;     printf("*pi=%d\n",*pi);
    *pl=20;     printf("*pl=%d\n",*pl);
    *pd=10.5;   printf("*pd=%.1f\n",*pd);
    strcpy(pc,"西施"); printf("*pc=%s\n",pc);
    strcpy(pst->name,"杨玉环"); pst->age=21;
    printf("name=%s,age=%d\n",pst->name,pst->age);
    
    // 释放动态分配的内存
    free(pi); free(pl); free(pd); free(pc); free(pst);
    }

    运行效果

    二、内存被耗尽

    使用动态分配内存技术的时候,分配出来的内存必须及时释放,否则会引起系统内存耗尽,这话说起来简单,好像很容易做到,但是在实际开发中,程序员往往是漏洞百出。

    内存问题是C程序员的主要问题之一,是初学者的恶梦。

    三、野指针

    野指针就是无效的指针,与空指针不同,野指针无法通过简单地判断是否为 NULL避免,而只能通过养成良好的编程习惯来尽力减少。

    1、指针变量未初始化

    指针变量刚被创建时不一定会自动初始化成为空指针(与编译器有关),它的缺省值是可能随机的,它会随便乱指。所以,指针变量在创建的同时应当被初始化,要么将指针的值设置为0,要么让它指向合法的内存。

    int *pi=0;

    int i;
    int *pi=&i;

    2、指针释放后之后未置空

    指针在free时会把指针所指的内存给释放掉,但指针不一定会赋值0(也与编译器有关),如果对释放后的指针进行操作,相当于非法操作内存。释放内存后应立即将指针置为0。

    free(pi);
    pi=0;

    四、应用经验

    1、数组申明的改进

    在C语言的早期标准中,定义数组必须用常量指明大小,不能用变量。

    char str[101];        // 可以这样
    int len=101;
    char str[len];         // 不可以这样

    程序在运行的时候,如果要定义一个字符串存放100个字符,那怎么办,只能通过动态分配内存技术。

    char *str=malloc(101);

    现在,定义数组可以用变量指明大小,就不必为数组动态分配内存了。

    还有,C++的string是一个变长的字符串,非常好用,程序员根本不必关心内存的问题。

    2、链表

    链表是C语言的一个经典的数据结构,相当于一个动态的结构体数组,非常巧妙,功能强大,但操作也麻烦,在这里我就不介绍了。

    在C++中,容器全完代替了链表的功能,极其好用,程序员也不必关心内存的问题。

    3、我的建议

    在中国,没有纯C程序员,如果他不会C++,不是他对C有多么执着,可能是不会C++。

    至少十年了,我不再使用动态内存分配技术,也想不到有什么场景非得用动态内存分配技术。

    哦,嵌入式开发可能是个例外,可能还有其它只能用C不能用C++的场景。

    动态内存分配并不是什么高大上的技术,我是一个实用的程序员,绝不给自己挖坑,这与水平高低无关。

    五、课后作业

    编写示例程序,把本章节介绍的知识点全部演示一遍,用程序演示可以加深您的理解和映象。

    六、版权声明

    C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。
    来源:C语言技术网(www.freecplus.net)
    作者:码农有道

    如果文章有错别字,或者内容有错误,或其他的建议和意见,请您留言指正,非常感谢!!!

    • 点赞
    • 收藏
    • 分享
    • 文章举报
    C语言技术网-码农有道 博客专家 发布了203 篇原创文章 · 获赞 507 · 访问量 12万+ 私信 关注
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: