C指针原理教程之垃圾回收-内存泄露分享!

一、内存泄露

1、正常的链表操作

下面程序建立一个10元素的链表,输出它们的节点,每个节点是一个员工的工号和年龄。最后删除每个节点,释放列表。

  dp@dp:~/memorytest % cat 1.c    #include <stdlib.h>  #include <stdio.h>  //code:myhaspl@myhaspl.com  //author:myhaspl  //date:2014-01-10  typedef struct listnode mynode;   struct listnode{    mynode *next;    int number;    int age;    };  mynode *addnode(mynode *prevnd,int number,int age){    mynode *ndtemp=(mynode*)malloc(sizeof(mynode));    prevnd->next=ndtemp;    ndtemp->number=number;    ndtemp->age=age;    ndtemp->next=NULL;    return ndtemp;  }  mynode *initlist(){    mynode *temp=(mynode*)malloc(sizeof(mynode));      temp->number=0;    temp->age=0;    temp->next=NULL;    return temp;  }  int main(){    mynode *mylist=initlist();    mynode *mytempnd=mylist;    int i=0;f悬挂指针    for(i=0;i<10;i++){      mytempnd=addnode(mytempnd,i,20+i);    }    //下面是正常的链表操作    //先输出链表元素    for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){      printf("id:%d,age:%dn",mytempnd->number,mytempnd->age);    }    //然后删除链表中的所有元素    mynode* oldtmpnd;    for (mytempnd=mylist->next;mytempnd!=NULL;){      printf("delete id:%dn",mytempnd->number);      oldtmpnd=mytempnd;      mytempnd=mytempnd->next;      free(oldtmpnd);    }    free(mylist);      return 0;    }    

下面是程序运行效果

  dp@dp:~/memorytest % gcc 1.c -o mytest    dp@dp:~/memorytest % ./mytest    id:0,age:20    id:1,age:21    id:2,age:22    id:3,age:23    id:4,age:24    id:5,age:25    id:6,age:26    id:7,age:27    id:8,age:28    id:9,age:29    delete id:0    delete id:1    delete id:2    delete id:3    delete id:4    delete id:5    delete id:6    delete id:7    delete id:8    delete id:9    dp@dp:~/memorytest %     

下面演示了垃圾的形成,这是内存泄露的一种方式,即在链表中,某些节点与链表中的其它节点失去联系,导致无法删除,下面故意让第4个结点的next指针指向null,失去与后面6个元素的联系。

  dp@dp:~/memorytest % cat 1.c      #include <stdlib.h>    #include <stdio.h>    //code:myhaspl@myhaspl.com    //author:myhaspl    //date:2014-01-10    typedef struct listnode mynode;     struct listnode{    mynode *next;    int number;    int age;    };    mynode *addnode(mynode *prevnd,int number,int age){    mynode *ndtemp=(mynode*)malloc(sizeof(mynode));    prevnd->next=ndtemp;    ndtemp->number=number;    ndtemp->age=age;    ndtemp->next=NULL;    return ndtemp;    }    mynode *initlist(){    mynode *temp=(mynode*)malloc(sizeof(mynode));    temp->number=0;    temp->age=0;    temp->next=NULL;    return temp;    }    int main(){    mynode *mylist=initlist();    mynode *mytempnd=mylist;    int i=0;    for(i=0;i<10;i++){    mytempnd=addnode(mytempnd,i,20+i);    }    //下面是正常的链表操作    //先输出链表元素    for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){    printf("id:%d,age:%dn",mytempnd->number,mytempnd->age);    }    //然后删除链表中的所有元素    for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){    printf("delete id:%dn",mytempnd->number);    free(mytempnd);    }    free(mylist);    //下面是形成内存泄露第一种情况-垃圾的演示    //生成并输出链表,这个与前面相同    mylist=initlist();    mytempnd=mylist;    i=0;    for(i=0;i<10;i++){    mytempnd=addnode(mytempnd,i,20+i);    }    for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){    printf("id:%d,age:%dn",mytempnd->number,mytempnd->age);    }    //删除链表,我们故意留下后面6个链表节点无法删除,导致后面6个链表节点形成垃圾    int j=0;    for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){    if (++j>3){    mytempnd->next=NULL;    break;    }    }    for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){    printf("delete id:%dn",mytempnd->number);    free(mytempnd);    j++;     }        return 0;    }    

下面是程序运行效果

  dp@dp:~/memorytest % gcc 1.c -o mytest    dp@dp:~/memorytest % ./mytest    id:0,age:20    id:1,age:21    id:2,age:22    id:3,age:23    id:4,age:24    id:5,age:25    id:6,age:26    id:7,age:27    id:8,age:28    id:9,age:29    delete id:0    delete id:1    delete id:2    delete id:3    delete id:4    delete id:5    delete id:6    delete id:7    delete id:8    delete id:9    id:0,age:20    id:1,age:21    id:2,age:22    id:3,age:23    id:4,age:24    id:5,age:25    id:6,age:26    id:7,age:27    id:8,age:28    id:9,age:29    delete id:0    delete id:1    delete id:2    delete id:3    dp@dp:~/memorytest %    

3、悬挂指针

一个指针不为空,但是指向一个无效的地址或耒知对象的地址,则这样的指针称为悬挂指针。

  dp@dp:~/memorytest % cat 2.c    #include <stdio.h>    #include <stdlib.h>    //code:myhaspl@myhaspl.com    //author:myhaspl    //date:2014-01-10    typedef struct listnode mynode;    struct listnode{    mynode *next;    int number;    int age;    };    mynode *addnode(mynode *prevnd,int number,int age){    mynode *ndtemp=(mynode*)malloc(sizeof(mynode));    prevnd->next=ndtemp;    ndtemp->number=number;    ndtemp->age=age;    ndtemp->next=NULL;    return ndtemp;    }    mynode *initlist(){    mynode *temp=(mynode*)malloc(sizeof(mynode));    temp->number=0;    temp->age=0;    temp->next=NULL;    return temp;    }    int main(){    mynode *mylist=initlist();    mynode *mytempnd=mylist;    int i=0;    for(i=0;i<10;i++){    mytempnd=addnode(mytempnd,i,20+i);    }    //下面是正常的链表操作    //先输出链表元素    for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){    printf("id:%d,age:%dn",mytempnd->number,mytempnd->age);    }    //然后删除链表中的所有元素    mynode* oldtmpnd;    for (mytempnd=mylist->next;mytempnd!=NULL;){    printf("delete id:%dn",mytempnd->number);    oldtmpnd=mytempnd;    mytempnd=mytempnd->next;    free(oldtmpnd);    }    free(mylist);    //下面是形成内存泄露第二种情况-悬挂指针的演示    //生成并输出链表,这个与前面相同    mylist=initlist();    mytempnd=mylist;    i=0;    for(i=0;i<10;i++){    mytempnd=addnode(mytempnd,i,20+i);    }    for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){    printf("id:%d,age:%dn",mytempnd->number,mytempnd->age);    }    //我们故意删除链表后面的4个节点,但是让第6个元素的next指向的地址无效,    //仍指向已经删除的第7个节点,导致悬挂指针    printf ("-------------------------n");    int j=0;    for (mytempnd=mylist->next;mytempnd!=NULL;){    oldtmpnd=mytempnd;    mytempnd=mytempnd->next;    if (++j>6){    printf("delete id:%dn",oldtmpnd->number);    free(oldtmpnd);    }    }        return 0;    }    

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/482786.html

(0)
上一篇 2020年11月9日
下一篇 2020年11月9日

精彩推荐