zoukankan      html  css  js  c++  java
  • 指针空间的申请与释放

    一、malloc()和free()的基本概念以及基本用法:
    1、函数原型及说明:
    void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。
    关于分配失败的原因,应该有多种,比如说空间不足就是一种。

    char *Ptr = NULL; Ptr = (char *)malloc(100 * sizeof(char)); if (NULL == Ptr) { exit (1); } gets(Ptr);
    void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。
    free(Ptr); Ptr = NULL; // code...

    free()到底释放了什么?这个问题比较简单,其实我是想和第二大部分的题目相呼应而已!哈哈!free()释放的是指针指向的内存!注意!释放的是内存,不是指针!这点非常非常重要!指针是一个变量,只有程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。因此,前面我已经说过了,释放内存后把指针指向NULL,防止指针在后面不小心又被解引用了。非常重要啊这一点! 就是这样!当然,具体情况要具体分析以及具体解决。比如说,你定义了一个指针,在一个函数里申请了一块内存然后通过函数返回传递给这个指针,那么也许释放这块内存这项工作就应该留给其他函数了。
    3、关于函数使用需要注意的一些地方:
    A、申请了内存空间后,必须检查是否分配成功。
    B、当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。
    C、这两个函数应该是配对。如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会
    出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。
    D、虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一
    些编译器的检查。
    好了!最基础的东西大概这么说!现在进入第二部分:

    二、malloc()到底从哪里得来了内存空间:
    1、malloc()到底从哪里得到了内存空间?答案是从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。就是这样!
    说到这里,不得不另外插入一个小话题,相信大家也知道是什么话题了。什么是堆?说到堆,又忍不住说到了栈!什么是栈?下面就另外开个小部分专门而又简单地说一下这个题外话:
    2、什么是堆:堆是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程 初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。
    什么是栈:栈是线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立。每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。
    以上的概念描述是标准的描述,不过有个别语句被我删除,不知道因为这样而变得不标准了^_^.
    通过上面对概念的描述,可以知道:
    栈是由编译器自动分配释放,存放函数的参数值、局部变量的值等。操作方式类似于数据结构中的栈。
    堆一般由程序员分配释放,若不释放,程序结束时可能由OS回收。注意这里说是可能,并非一定。所以我想再强调一次,记得要释放!

    一、定义指针的时候一定要初始化。

    变量定义的时候给变量初始化,这是保证不出错的一个很好的习惯。尤其是在指针的使用上,如果我们没有给指针初始化,就会出现野指针,该指针的指向并不是我们所希望的,一旦错误的释放了这个指针,就会发生内存的访问。那么如何初始化指针变量呢,一般有以下几种方法:
    1、初始化空指针
    int* pInteger=NULL;
    2、用已有的变量初始化
    int length=5;
    int* pInteger=&length;
    3、用内存分配函数给指针分配空间
    int* pInteger=(int*)malloc(10*sizeof(int));//为指针分配大小为10个整数的内存空间。
    二、正确的申请和释放内存
    指针使用之后,如果不释放指针所使用的内存,就会造成内存的泄露,这样就会有大量内存由于没能释放,别的程序不可以使用这部分内存,如果一个程序不停申请内存而不去释放内存,很快就会造成系统的崩溃。那么如何正确的申请和释放内存呢。
    1、指针初始化,上面已讲
    2、正确的申请内存
    如何申请内存才算是正确的申请内存呢?首先要判断指针是否为空,如果不为空,则释放该指针所指向的内存块,如果不释放这块内存,而直接就申请内存,就会造成内存的泄露。申请内存后,一定要判断是否申请成功。
    如:int* pInteger=NULL;//指针定义处
    ...
    if(pInteger != NULL)
    {
    free(pInteger);
    pInteger=NULL;//指针释放之后并不为空,要设置其为空
    }
    pInteger=(int*)malloc(10*sizeof(int));
    if(pInteger != NULL)
    {
    printf("内存申请没有成功/n!");
    exit(0);
    }
    ...
    3、内存释放
    程序使用完了指针,一定要记得释放指针指向的内存。释放后一定要记得设置指针为空指针。因为free函数在释放指针后,只是单纯的释放了该指针指向的内存空间,而没有将指针赋为空值。所以一定要记得在释放指针后将指针赋为空值。
    如:
    int* pInteger=NULL;//指针定义处
    ...
    free(pInteger);//释放指针
    pInteger=NULL; //指针赋为空值
    三、使用指针时一定要判断指针是否为空
    在使用指针时一定要判断指针是否为空,如果为空,则做相应的操作。如果不做判断,则可能错误的使用空指针。
    如:char* dest=NULL;
    ...
    strcpy(dest,"string");//如果dest为空则出错
     
    正确的使用方法为:
    if(dest == NULL)
    {
    dest=(char*)malloc(7*sizeof(char));//因为字符串以“/0”结束,
    //所以要申请7个字符的内存
    //判断内存申请是否成功
    ...
    }
    strcpy(dest,"string");
     
    在指针的使用过程中,基本上要注意的问题就是这些
  • 相关阅读:
    164 Maximum Gap 最大间距
    162 Find Peak Element 寻找峰值
    160 Intersection of Two Linked Lists 相交链表
    155 Min Stack 最小栈
    154 Find Minimum in Rotated Sorted Array II
    153 Find Minimum in Rotated Sorted Array 旋转数组的最小值
    152 Maximum Product Subarray 乘积最大子序列
    151 Reverse Words in a String 翻转字符串里的单词
    bzoj3994: [SDOI2015]约数个数和
    bzoj 4590: [Shoi2015]自动刷题机
  • 原文地址:https://www.cnblogs.com/I-L-o-v-e-z-h-o-u/p/4950528.html
Copyright © 2011-2022 走看看