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 \n",j,node.v);
    }
    freeLinearStack(pstack);
}

  

时间: 2024-10-28 10:40:25

C语言中内存管理规范的相关文章

JVM内存管理------JAVA语言的内存管理概述

引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓狂的内存溢出和泄露的问题. 可怕的事情还不只如此,有些使用其它语言开发的程序员,给JAVA程序员扣上了一个"不懂内存"的帽子,这着实有点让人难以接受.毕竟JAVA当中没有malloc和delete.没有析构函数.没有指针,刚开始接触JAVA的程序员们又怎么可能接触内存这一部分呢,更何况有不

C语言中内存的管理

一  Handler作用和概念 包含线程队列和消息队列,实现异步的消息处理机制,跟web开发的ajax有异曲同工之妙. 1.运行在某个线程上,共享线程的消息队列: 2.接收消息.调度消息,派发消息和处理消息: 3.实现消息的异步处理: Handler能够让你发送和处理消息,以及Runnable对象:每个Handler对象对应一个Thread和Thread的消息队列.当你创建一个Handler时,它就和Thread的消息队列绑定在一起,然后就可以传递消息和runnable对象到消息队列中,执行消息

C语言动态内存管理

1-概述 动态存储管理的基本问题是:系统如何按请求分配内存,如何回收内存再利用.提出请求的用户可能是系统的一个作业,也可能是程序中的一个变量. 空闲块 未曾分配的地址连续的内存区称为"空闲块". 占用块 已分配给用户使用的地址连续的内存区称为"占用块". 系统刚刚启动时,整个内存可看做一个大的"空闲块",随着用户请求的进入,系统依次分配相应的内存. 在系统运行过程中,内存被分为两大部分:低地址区(若干占用块)和高地址区(空闲块). 经过一段时间后

C语言中内存分配

C语言中内存分配 在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重点介绍C程序中内存的分配,以及C语言编译后的可执行程序的存储结构和运行结构,同时还介绍了堆空间和栈空间的用途及区别. 第2节主要介绍C语言中内存分配及释放函数.函数的功能,以及如何调用这些函数申请/释放内存空间及其注意事项. 3.1 内存管理基本概念 3.1.1 C程序内存分配 1

Swift语言的内存管理哦,还等什么?点进来!

//*********Swift语言的内存管理基础************* //内存管理:针对的是实例的内存占用的管理(放在堆里面) //实例:1,由class类型构建的实例 2.闭包对象 /* 内存管理技术:ARC:Automatic Reference Count 自动:由于语言本身帮我们管理内存,不需要我们手机去管理 比如在c中就调用dealloc() 引用:let p = Person() p就是对Person()这个对象的一个引用 计数: let p = Person()   +1

[转载]对iOS开发中内存管理的一点总结与理解

对iOS开发中内存管理的一点总结与理解 做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作的理解是衡量一个程序员成熟与否的一个标准.好了,闲话不说,下面进入正题. 众所周知,ObjectiveC的内存管理引用的一种叫做“引用计数“ (Reference Count)的操作方式,简单的理解就是系统为每一个创建出来的对象,(这里要注意,只是对象,NSObject的子类,基本类型没有‘引用计数’)

C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针

(1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放,造成内存泄露,下面的例子就可能造成20个字节的泄露,内存泄露不是一个立即会引发故障的错误,但是 它将消耗系统内存. void function1() { char *pa; pa = (char*)malloc(sizeof(char)*20); if(NULL !=pa) { strcpy(pa,"hello"); printf("pa = %x\n",

C语言中内存分配问题:

推荐: C语言中内存分配 Linux size命令和C程序的存储空间布局 本大神感觉,上面的链接的内容,已经很好的说明了: 总结一下: 对于一个可执行文件,在linux下可以使用 size命令列出目标文件各部分占的字节数:分为:text段.data段与bss段:(参考:Linux size命令和C程序的存储空间布局) 对于一个可执行文件,它的存储空间包括: 1. 代码区(text segment).存放CPU执行的机器指令(machine instructions) 2. 全局初始化数据区/静态

C语言中内存分配 (转)

在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重点介绍C程序中内存的分配,以及C语言编译后的可执行程序的存储结构和运行结构,同时还介绍了堆空间和栈空间的用途及区别. 第2节主要介绍C语言中内存分配及释放函数.函数的功能,以及如何调用这些函数申请/释放内存空间及其注意事项. 3.1 内存管理基本概念 3.1.1 C程序内存分配 1.C程序结构 下面