zoukankan      html  css  js  c++  java
  • C语言中内存管理规范

    一、内存申请

           1.建议使用calloc申请内存,尽量不要使用malloc。

           calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。

           2.申请内存大小必须大于0.

        (1)使用0字节长度申请内存的行为是没有定义的,在引用内存申请函数返回地址时会引发不可预知错误,对于可能出现申请0长度内存的情况非常有必要判断,避免出现这种情况。

            (2)使用负数长度申请内存,负数会被当成一个很大的无符号整数,导致申请内存过大而出现失败。

           3.申请内存后检查是否申请成功,即检查返回指针是否为NULL,即是否为0。

    二、内存释放 

            1.申请的内存一定需要释放,有且仅能释放一次

            2.禁止释放或函数内返回非动态申请的内存(栈中的内存,函数中的临时变量等)

       3.指针释放后必须将指针指向空指针,否则会出现野指针的情况。

    三、附加一个C实现的存储二叉树元素的动态栈

    #include<stdio.h>
    #include<string.h>
    #include<malloc.h>
    #define LH_MALLOC(pMemory,Type,Size)  
            if(Size > 0)
            {
                pMemory=(Type*)calloc(Size/sizeof(Type),sizeof(Type));
            }
            else
            {
                pMemory=NULL;
            }
    
    #define LH_FREE(p)  if(NULL != p){free(p);p=NULL;}
    
    #define LH_MEMORY_MOV(dst,dstSize,src,srcSize,Type)
               LH_MALLOC(dst,Type,dstSize)
               memcpy(dst,src,srcSize);
              LH_FREE(src)
    
    typedef struct tagTreeNode
    {
        int v;
        struct tagTreeNode* pleft;
        struct tagTreeNode* pright;
    }TreeNode;

    typedef struct tagLinearStack
    {
       TreeNode* ptrees;
       int* ptags;
       int maxsize;
       int index;
    }LinearStack;

    /*获取一个栈指针*/
    LinearStack* getALinearStack()
    {
        LinearStack* pstack;
        LH_MALLOC(pstack,LinearStack,sizeof(LinearStack));
        return pstack;
    }
    
    /*释放栈,与getALinearStack成对使用*/
    void freeLinearStack(LinearStack* pstack)
    {
        LH_FREE(pstack->ptags);
        LH_FREE(pstack->ptrees);
        LH_FREE(pstack);
    }
    
    /*入栈*/
    void push(LinearStack* pstack,TreeNode node)
    {
        if(pstack->ptrees == 0 && pstack->ptags == 0)
        {
            LH_MALLOC(pstack->ptrees,TreeNode,sizeof(TreeNode)*5);
            LH_MALLOC(pstack->ptags,int,sizeof(int)*5);
            pstack->maxsize=5;
        }
    
        if(pstack->index < pstack->maxsize)
        {
           pstack->ptrees[pstack->index++]=node;
        }
        else
        {
           TreeNode* tmpTrees;
           int* tmptags;
           LH_MEMORY_MOV(tmpTrees,
                       sizeof(TreeNode)*pstack->maxsize*2,
                     pstack->ptrees,
                        sizeof(TreeNode)*pstack->maxsize,
                        TreeNode);
    
           LH_MEMORY_MOV(tmptags,
                       sizeof(int)*pstack->maxsize*2,
                      pstack->ptags,
                      sizeof(int)*pstack->maxsize,
                      int);
           pstack->ptrees=tmpTrees;
           pstack->ptags=tmptags;
           pstack->maxsize=pstack->maxsize*2;
           pstack->ptrees[pstack->index++]=node;
        }
    }
    
    /*弹出栈*/
    TreeNode pop(LinearStack* pstack)
    {
        if(pstack->index > 0)
        {
           return pstack->ptrees[--pstack->index];
        }
    }
    
    void main()
    {
        LinearStack* pstack=getALinearStack();
        if(NULL == pstack) 
           retrun;
        for(int i=0;i<60000;i++)
        {
            a.v=i;
            push(pstack,a);
        }
        for(int j=0;j<60000;j++)
        {
        TreeNode node=pop(pstack);
            printf("%d: %d 
    ",j,node.v);
        }
        freeLinearStack(pstack);
    }

    四、二叉树非递归遍历方法

    void preOrder(TreeNode* pnode)
    {
      LinearStack* pstack=getALinearStack();
      while(NULL != pnode || pstack->index > 0)
      {
          while(NULL!=pnode)
          {
              printf("%c ",pnode->v);
              push(pstack,*pnode);
              pnode=pnode->pleft;
          }
          pnode=pop(pstack);
          pnode=pnode->pright;
      }
      freeLinearStack(pstack);
    }
    
    void middleOrder(TreeNode* pnode)
    {
     LinearStack* pstack=getALinearStack();
     while(NULL != pnode || pstack->index > 0)
     {
         while(NULL!=pnode)
         {
             push(pstack,*pnode);
             pnode=pnode->pleft;
         }
         pnode=pop(pstack);
         printf("%c ",pnode->v);
         pnode=pnode->pright;
     }
     freeLinearStack(pstack);
    }
    
    void postOrder(TreeNode* pnode)
    {
     LinearStack* pstack=getALinearStack();
     while(NULL != pnode || pstack->index > 0)
     {
         while(NULL != pnode)
         {
            push(pstack,*pnode);
            pstack->ptags[pstack->index-1]=0;
            pnode=pnode->pleft;
         }
         if(pstack->ptags[pstack->index-1]==0)
         {
            pstack->ptags[pstack->index-1]=1;
            pnode=pstack->ptrees[pstack->index-1].pright;
         }
         else
         {
             while(pstack->ptags[pstack->index-1]==1)
             {
                 pnode=pop(pstack);
                 printf("%c ",pnode->v);
             }
             pnode=NULL;
         }
     }
     freeLinearStack(pstack);
    }
    
    void init()
    {
        a.v='a';a.pleft=&b;a.pright=&c;
        b.v='b';b.pleft=&d;b.pright=&e;
        c.v='c';c.pleft=0;c.pright=0;
        d.v='d';d.pleft=0;d.pright=&f;
        e.v='e';e.pleft=&g;e.pright=0;
        f.v='f';f.pleft=0;f.pright=0;
        g.v='g';g.pleft=0;g.pright=0;
    }
    
    
    void main()
    {
        init();
        postOrder(&a);
    }

     五、线索二叉树

    typedef enum{Link,Thread} PointerTag;
    
    typedef struct tagTreeNode
    {
        char v;
        PointerTag ltag,rtag;
        struct tagTreeNode* pleft;
        struct tagTreeNode* pright;
    }TreeNode;
    TreeNode a,b,c,d,e,f,g;
    void init()
    {
        a.v='a';a.pleft=&b;a.pright=&c;
        b.v='b';b.pleft=&d;b.pright=&e;
        c.v='c';c.pleft=0;c.pright=0;
        d.v='d';d.pleft=0;d.pright=&f;
        e.v='e';e.pleft=&g;e.pright=0;
        f.v='f';f.pleft=0;f.pright=0;
        g.v='g';g.pleft=0;g.pright=0;
    }
    TreeNode *pre;
    void InitThreadRootTree(TreeNode* ptree)
    {
        if(NULL != ptree)
        {
            InitThreadRootTree(ptree->pleft);
             
            if(ptree->pleft == NULL)
            {
                ptree->ltag=Thread;
                ptree->pleft=pre;
            }
            if(pre->pright == NULL)
            {
                pre->rtag=Thread;
                pre->pright=ptree;
            }
            pre=ptree;
    
            InitThreadRootTree(ptree->pright);
        }
    }
    void BuildThread(TreeNode* phead,TreeNode* ptreeRoot)
    {
        if(NULL == ptreeRoot)
        {
            phead->ltag=Link;
            phead->pleft=phead;
        }
        else
        {
            
            phead->ltag=Link;
            phead->pleft=ptreeRoot;
            pre=phead;
    
            InitThreadRootTree(ptreeRoot);
    
            pre->pright=phead;
            pre->rtag=Thread;
            phead->pright=pre;
        }
    }
    
    void midOrderThread(TreeNode* phead)
    {
        TreeNode* treeNode = phead->pleft;
        while(phead != treeNode)
        {
              while(treeNode->ltag == Link)
              {
                treeNode=treeNode->pleft;
              }
              printf("%c ",treeNode->v);
              while(treeNode->rtag==Thread && treeNode->pright != phead)
              {
                  treeNode=treeNode->pright;
                   printf("%c ",treeNode->v);
              }
              treeNode=treeNode->pright;
        }
    }
    
    void main()
    {
        init();
        TreeNode head;
        head.rtag=Link;
        head.pright=&head;
        BuildThread(&head,&a);
        midOrderThread(&head);
    }

           

  • 相关阅读:
    html5数字和颜色输入框
    WinForm设置右键菜单
    设置窗体透明C#代码
    C#调用windows api示例
    使用VS GDB扩充套件在VS上远端侦错Linux上的C/C++程序
    javascript系统时间测试题
    博客园学习的好地方
    基于jQuery的自适应图片左右切换
    HTML+CSS代码橙色导航菜单
    ASP.NET使用UpdatePanel实现AJAX
  • 原文地址:https://www.cnblogs.com/lh218/p/5373907.html
Copyright © 2011-2022 走看看