精华内容
下载资源
问答
  • C语言动态分配内存1 动态内存分配基础2 动态内存分配实例3 动态内存分配进阶 动态分配内存基础 动态分配内存概述什么时候需要动态分配内存实例顺序对一批文件进行解析但是不知道文件的大小如何建立缓冲区 malloc函数...
  • C语言动态分配内存.ppt
  • 笔者为C语言新手,想分享...作用:动态开辟byte_size个字节的内存空间,不进行初始化,返回指向此内存的指针,此指针所指数据类型没有确定,需要强转。 举例:int *p=(int *)malloc(5*sizeof(int)); 例解:动态开...

     

     

    笔者为C语言新手,想分享并总结下相关学习心得,如有错误,望各位大牛指正。

     

    malloc

    原型:void *malloc(int byte_size);

    作用:动态开辟byte_size个字节的内存空间,不进行初始化,返回指向此内存的指针,此指针所指数据类型没有确定,需要强转。

    举例:int *p=(int *)malloc(5*sizeof(int));

    例解:动态开辟5*4=20个字节大小的空间,返回空间首地址指针并强转为int *型后赋予指针变量p。

    注意:malloc只开辟空间,不初始化,即只将此空间由未占用状态变为已占用状态,空间内存储的具体数据未指定改变。函数返回值是空间首地址,上例中赋给了p变量。

     

    calloc

    原型:void *calloc(int n,int type_byte_size);

    作用:动态开辟n*type_byte_size个字节,将每个字节均初始化为ascii码0,返回指向此内存的指针,此指针所指数据类型没有确定,需要强转。

    举例:int *p=(int *)calloc(5,sizeof(int));

    例解:动态开辟5*4=20个字节大小的空间,其中每个字节均赋初值0,返回空间首地址指针并强转为int *型后赋予指针变量p。

    注意:calloc在malloc的基础上将空间按字节初始化为ascii码0,且其参数有两个,两参数之积为空间总字节数。

     

    realloc

    原型:void *realloc(void *p,int byte_size);

    作用:若p所指空间连续大小(单位字节)大于byte_size,则从首地址开始连续地扩充开辟p所指空间至byte_size字节,不对空间再次赋值,将空间地址指针返回;若p所指空间连续大小小于byte_size,则新开辟byte_size字节大小的空间,将p指向的空间内的数据复制进新空间,之后释放p所指空间(此时p为NULL),返回指向新空间的指针,此指针所指数据类型没有确定,需要强转。

    举例:int *p=(int *)calloc(5,sizeof(int));

          p =(int*)realloc(p,10*sizeof(int));

    例解:首句中p为5*4=20字节的空间指针并按字节初始化为ascii码0,(int *)强转后才限定了指向空间的每个元素为int型。后句将p所指空间扩充为10*4=40字节的空间指针,未对其二次赋值,故此时p[0]~p[4]为0,p[5]~p[9]未初始化。

    注意:realloc的第一个参数必须是动态开辟的地址,不能是静态定义的数组的地址,结构体数组也不行。具体原因我也不清楚...

     

    memset

    原型:void *memset(void *p,char c,int byte_size);

    作用:将p所指的大小为byte_size字节的空间按字节赋值为字符变量c(即指定的ascii码),返回空间首地址指针,此指针所指数据类型没有确定,需要强转。memset所在头文件为memory.h。

    举例:int *p=(int *)malloc(5*sizeof(int));

          p =(int*)memset(p,3,5*sizeof(int));

    例解:第二句中将p所指空间(5*4个字节大小)按字节赋值为ascii码3,即每个32位均为00000011000000110000001100000011,转化为十进制为50529027。之后将返回的指针强转为(int*)后赋给p。

    注意:按字节赋予ascii码值并非按原数据类型赋值,强转后确定数据类型,输出结果会很“奇怪”。

     

    测试代码:(malloc省略)

    // 动态分配内存测试.cpp: 定义控制台应用程序的入口点。

    //

     

    #include "stdafx.h"

    #include "stdio.h"

    #include "stdlib.h"

    #include" conio.h"

    #include "memory.h"

    int _tmain(int argc,_TCHAR* argv[])

    {

             int *p;

             p=(int *)calloc(5,sizeof(int));

             if(!p)

             {

                       printf("calloc分配失败1");

                       _getch();

                       exit(0);

             }

             for(int i=0;i<5;++i)

                       printf("c:p[%d]=%d\n",i,p[i]);

             p=(int *)realloc(p,10*sizeof(int));

             if(!p)

             {

                       printf("realloc分配失败2");

                       _getch();

                       exit(0);

             }

             for(int i=0;i<10;++i)

                       printf("r:p[%d]=%d\n",i,p[i]);

             int *q=(int *)memset(p,3,10*sizeof(int));

             if(!q)

             {

                       printf("memset分配失败3");

                       _getch();

                       exit(0);

             }

             p=(int *)memset(p,3,10*sizeof(int));

             for(int i=0;i<10;++i)

                       printf("m:q[%d]=%d\n",i,q[i]);

             for(int i=0;i<10;++i)

                       printf("m:p[%d]=%d\n",i,p[i]);

             free(p);

             q=NULL;

             _getch();

             return0;

    }

     

     

    运行结果:

     

     

     

     

     

     

     

    32位按字节赋ascii码3(每8位均为00000011),转为10进制(DEC)如下:

     

    展开全文
  • C语言动态分配内存PPT学习教案.pptx
  • C语言动态分配内存

    万次阅读 2018-06-18 15:45:24
    C语言动态分配内存 malloc 动态开辟内存的函数: void* malloc (size_t size); 这个函数向内存申请⼀块连续可⽤的空间,并返回指向这块空间的指针 如果开辟成功,则返回⼀个指向开辟好空间的指针 如果开辟...

    C语言动态分配内存

    malloc

    动态开辟内存的函数:

    void* malloc (size_t size);

    这个函数向内存申请⼀块连续可⽤的空间,并返回指向这块空间的指针
    如果开辟成功,则返回⼀个指向开辟好空间的指针
    如果开辟失败,则返回⼀个NULL指针,因此malloc的返回值⼀定要做检查
    返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使⽤的时候使⽤者自己来决定
    如果参数 size 为0, malloc的⾏为是标准是未定义的,取决于编译器

    calloc

    calloc 函数也⽤来动态内存分配。函数原型如下:

    void *calloc(size_t num, size_t size);

    函数的功能是为 num 个⼤⼩为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0。
    与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。

    realloc

    realloc函数的出现让动态内存管理更加灵活。
    有时我们会发现过去申请的空间不够用或者用不完,那 realloc 函数就可以做到对动态开辟内存大小的调整。 函数原型如下:

    void* realloc (void* ptr, size_t size);

    ptr 是要调整的内存地址
    size 调整之后新大小
    返回值为调整之后的内存起始位置。
    这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
    realloc在调整内存空间的是存在两种情况:
    1. 原有空间之后有⾜够⼤的空间
    2. 原有空间之后没有⾜够⼤的空间

    当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。

    当是情况2 的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。并且原来旧的地址就会被自动释放掉。

    free

    函数free,专门是⽤来做动态内存的释放和回收的,函数原型如下:

    void free (void* ptr);

    如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
    如果参数 ptr 是NULL指针,则函数什么事都不做。

    深究

    这里我不禁产生了个疑问:既然会对已经开辟的内存进行realloc、free,那编译器是怎么知道开辟的这段内存有多大呢?

    在VS2013中,我做了一个测试:

    int main()
    {
        int *p = (int *)malloc(sizeof(int));    
        return 0;
    }

    在测试中,我们申请了4个字节大小的空间。

    单步调试后,跳转到malloc函数的定义处:
    malloc函数的定义

    继续F11加F10,可以在dbgheap.c文件中看到这样一句话:

    blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;

    这里的_CrtMemBlockHeader是一个结构体。它的大小是多少呢?转到它的定义处发现:

    typedef struct _CrtMemBlockHeader
    {
            struct _CrtMemBlockHeader * pBlockHeaderNext;
            struct _CrtMemBlockHeader * pBlockHeaderPrev;
            char *                      szFileName;
            int                         nLine;
    #ifdef _WIN64
            /* These items are reversed on Win64 to eliminate gaps in the struct
             * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is
             * maintained in the debug heap.
             */
            int                         nBlockUse;
            size_t                      nDataSize;
    #else  /* _WIN64 */
            size_t                      nDataSize;
            int                         nBlockUse;
    #endif  /* _WIN64 */
            long                        lRequest;
            unsigned char               gap[nNoMansLandSize];
            /* followed by:
             *  unsigned char           data[nDataSize];
             *  unsigned char           anotherGap[nNoMansLandSize];
             */
    } _CrtMemBlockHeader;

    可以看到,两个struct _CrtMemBlockHeader *占了8个字节,再加上char *int,就是16个字节;然后无论是不是64位系统,都要加上intsize_t的8个字节,就是24个字节;然后再加上longunsigned char的5个字节,总共有29个字节。又因为结构体的对齐规则,所以整个_CrtMemBlockHeader的大小就是32个字节。

    那其他两个呢?
    在dbgint.h的315行,会看到宏nNoMansLandSize的值#define nNoMansLandSize 4
    监视
    另一个nSize的大小刚好为4,blockSize的大小就是32+4+4=40个字节。

    接着往下看,在圈起来的部分,可以看到系统用刚刚的blockSize大小到堆区去申请空间了。
    开辟空间

    现在意思就很明显了:在主函数中我们申请了4个字节大小的空间,而实际是在堆上多申请了32加4个字节。那这多出来的字节用来干嘛了呢?继续往下调试代码,可以看到:

    系统往刚刚在堆中申请的空间做了初始化操作:往真正用户需要的四个字节中填充0XCD;往用户需要空间的首尾以外的4个字节,填充0XFD
    填充

    最后,返回给p的就是那被填充0XCD的四个字节:

    至此,结果已经出来了:系统在动态分配内存时并不是真正用户要多少就申请多少,而是会在每一个用户申请空间时多申请32+4个字节的空间,用来标记和管理分配给用户的空间。对于用户而言,在不出意外的情况下,每次感觉“自己真正申请了n个字节”,而实际上却不是这样。

    既然每次动态地在堆上申请空间时,都会多申请32+4个字节的空间。若是在做链表时每次都只申请很少的字节,那将会造成很大的空间浪费。所以用C语言的动态开辟空间时,因注意到这一点。

    展开全文
  • C语言动态内存分配函数

    万次阅读 多人点赞 2019-06-02 23:46:57
    目录 1.malloc()2.free()3.calloc()4.realloc()5....所开辟的内存是在栈中开辟的固定大小的 ,如a是4字节 ,数组b是40字节 ,并且数组在申明时必须指定其长度 , 因为数组的内存是在编译时分配好的 . 如果我们想在...

    目录

    1.malloc()
    2.free()
    3.calloc()
    4.realloc()
    5.小结


     在C中我们开辟内存空间有两种方式 :
    1.静态开辟内存 : 例如:

    int a;
    int b[10];

     这种开辟内存空间的特点是
    所开辟的内存是在栈中开辟固定大小的 ,如a是4字节 ,数组b是40字节 ,并且数组在申明时必须指定其长度 , 如果是全局数组的话,内存是在编译时分配好的,如果是局部变量数组的话,运行时在栈上静态分配内存。不管是全局数组还是局部数组,它们都有一个特点,那就是数组大小是确定的,是代码中写死的。那如果我们想在程序运行时才确定一个数组的大小 , 前两种在栈上分配内存的方法显然是不行的 , 举个例子 :

    int n;
    scanf("%d", &n);
    int a[n];

    这样编写会在编译时出错 , 编译器会提醒[ ]中应为常量表达式 , 在C中定义数组时可以用的有以下几种 ,例:

    #define N 10
    enum NUM{
    	M=10
    };
    int a1[N];
    int a2[10];
    int a3[M];

    需要注意的是 ,C中const int n =10 ; n并不能作为数组长度定义数组 , 但C++中则可以 , 
    但我们对于开辟空间的需求 , 往往不限于此 , 最常见的定义数组时数组大小在程序运行时才知道的 , 静态开辟就已经无能为力 . 当然有静态开辟 ,肯定也有动态开辟 ,接下来我们就来看动态开辟内存空间

    2.动态开辟内存 :
    在C中动态开辟空间需要用到三个函数 :
    malloc(), calloc(), realloc() ,这三个函数都是向堆中申请的内存空间.
    在堆中申请的内存空间不会像在栈中存储的局部变量一样 ,函数调用完会自动释放内存 , 需要我们手动释放 ,就需要free()函数来完成.
    下面让我们来看看这几个函数各自的特点, 用法, 区别, 联系.

    1.malloc()

    void * malloc(size_t size)

    1).malloc()函数会向中申请一片连续可用内存空间
    2).若申请成功 ,,返回指向这片内存空间的指针 ,若失败 ,则会返回NULL, 所以我们在用malloc()函数开辟动态内存之后, 一定要判断函数返回值是否为NULL.
    3).返回值的类型为void*型, malloc()函数并不知道连续开辟的size个字节是存储什么类型数据的 ,所以需要我们自行决定 ,方法是在malloc()前加强制转 ,转化成我们所需类型 ,如: (int*)malloc(sizeof(int)*n).
    4).如果size为0, 此行为是未定义的, 会发生未知错误, 取决于编译器

    具体怎么用呢 ,举个例子 .

    int *p = NULL;
    int n = 0;
    scanf("%d", &n);
    p = (int*)malloc(sizeof(int) * n);
    if(p != NULL){
        //....需要进行的操作
    }
    

    这时就相当于创建了一个数组 p[n] ,这个n的值并不需要像定义一个普通数组一样必须是常量, 可以使程序运行时得出的, 或是用户输入的


     2.free()

    void free(void* ptr)
    在堆中申请的内存空间不会像在栈中存储的局部变量一样 ,函数调用完会自动释放内存 , 如果我们不手动释放, 直到程序运行结束才会释放, 这样就可能会造成内存泄漏, 即堆中这片内存中的数据已经不再使用, 但它一直占着这片空间, (通俗说就是就是占着茅坑不拉屎), 所以当我们申请的动态内存不再使用时 ,一定要及时释放 .

    1).如果ptr没有指向使用动态内存分配函数分配的内存空间,则会导致未定义的行为。
    2).如果ptr是空指针,则该函数不执行任何操作。
    3).此函数不会更改ptr本身的值,因此它仍指向相同(现在已经无效)的位置(内存)
    4).free()函数之后需要将ptr再置空 ,即ptrNULL;如果不将ptr置空的话 ,后面程序如果再通过ptr会访问到已经释放过无效的或者已经被回收再利用的内存, 为保证程序的健壮性, 一般我们都要写ptrNULL;

    注意 : free()不能重复释放一块内存, 如:

    free(ptr);
    free(ptr);

     是错的, 已经释放过的内存不能重复释放, 会出现内存错误 .

    free()具体用法, 举个例子 :

    int *p = NULL;
    int n = 0;
    scanf("%d", &n);
    p = (int*)malloc(sizeof(int) * n);
    if(p != NULL){
        //....需要进行的操作
    }
    //操作完成 ,不再使用这片内存空间
    free(p);
    p = NULL;

     


     

     3.calloc()

    void * calloc(size_t num,size_t size)
    malloc()函数的区别只在于, calloc()函数会在返回地址之前将所申请的内存空间中的每个字节都初始化为0 .

    1).calloc()函数功能是动态分配num个大小(字节长度)为size的内存空间 .
    2).若申请成功 ,,返回指向这片内存空间的指针 ,若失败 ,则会返回NULL, 所以我们在用calloc()函数开辟动态内存之后, 一定要判断函数返回值是否为NULL.
    3).返回值的类型为void*型, calloc()函数虽然分配numsize大小的内存空间 ,但还是不知道存储的什么类型数据 ,所以需要我们自行决定 ,方法是在calloc()前加强制转 ,转化成我们所需类型 ,如: (int*)calloc(num, sizeof(int)).
    4).如果sizenum有一个或都为0, 此行为是未定义的, 会发生未知错误, 取决于编译器

    所以如何我们对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数来完成这个需求。
    例如 :


    4.realloc()

    void * realloc(void * ptr,size_t size)

    realloc()函数让动态内存管理更加灵活 .在程序运行过程中动态分配内存大小,  如果分配的太大 ,则浪费空间, 如果太小, 可能还是会出现不够用的情况 .为了合理的利用内存,我们一定会对内存的大小做灵活的调整。那realloc() 函数就可以做到对动态开辟内存大小的调整(既可以往大调整, 也可以往小了调整) .

    1).ptr为需要调整的内存地址
    2).size为调整后需要的大小(字节数)
    3).若调整成功, 返回值为调整大小后内存的起始位置(也就是指向调整后内存的指针), 若失败(当没有内存可以分配时, 一般不会出现), 则返回NULL, 所以还是要对返回值判空
    4).如果ptr是空指针, 则和malloc()函数一样作用一样

    注意 : realloc()函数在扩大内存空间时有两种情况
    1).ptr所指的内存后有足够的内存空间用来扩展 ,如图 :

    2).ptr所指内存后没有足够的空间来扩展 ,如图 :
     

    当第二种情况时, 若申请新的内存空间成功, 会将ptr所指向的内存中的内容拷贝到新的内存空间中, ptr所指向的内存会被释放, 返回新得内存地址, 若不成功 ,ptr 所指内存不会被释放, 函数返回NULL


    5.小结

    1).malloc()calloc()函数用法一样, 唯一的区别是calloc()会对所申请内存的每个字节初始化为0

    2).malloc()calloc(), realloc()申请的内存不再使用时 ,一定要用free()释放 ,否则会造成内存泄漏

    3).p = realloc(ptr, size)函数返回值不为空时, 释放内存时不需写free(ptr) ,只需写free(p) 

     

     

    展开全文
  • 在C中动态分配内存的基本步骤有: 1,用malloc类的函数分配内存; 2,用这些内存支持应用程序 3,用free函数释放内存 二、动态内存分配函数  malloc :从堆上分配内存  realloc : 在之前分配的内存块的基础上,将内存...

    #include<stdio.h>

    /**
    在C中动态分配内存的基本步骤有:
    1,用malloc类的函数分配内存;
    2,用这些内存支持应用程序
    3,用free函数释放内存
    二、动态内存分配函数
        malloc :从堆上分配内存
        realloc : 在之前分配的内存块的基础上,将内存重新分配为更大或者更小的部分
        calloc: 从堆上分配内存并清零
        free:将内存块返回堆
    */
    void mainaa()
    {
        int *pi = (int*) malloc(sizeof(int));
        *pi = 5;
        printf("*pi:%d\n",*pi);
        free(pi);
    }
    //为字符串分配内存,将其初始化,并逐个字符打印字符串,然而每次迭代name都会增加1,最后name会指向字符串结尾的NUL字符,
    //分配内存的起始地址丢失了
    void mainbb()
    {
        //为10个双精度浮点数分配空间,需要80个字节
        //double *pd = (double*)malloc(NUMBER_OF_DOUBLES*sizeof(double));
        //以下程序只分配了10个字节
        const int NUMBER_OF_DOUBLES = 10;
        double *pd = (double*)malloc(NUMBER_OF_DOUBLES);

        //初始化静态或全局变量时不能调用函数,下面的代码声明一个静态变量,并试图用
        //malloc来初始化,这样会产生一个编译时错误消息
        //static int *pi = malloc(sizeof(int));

        char *name = (char*)malloc(strlen("Susan")+1);
        strcpy(name,"Susan");

        while(*name != 0){
            printf("%c",*name);
            name++;
        }
    }
    /**
        使用calloc函数
        calloc会在分配的同时清空内存,该函数的原型如下:void *calloc(size_t numElements,size_t elementSize);
        calloc函数会根据numElements和elementSize两个参数的乘积来分配内存,并返回一个指向内存的第一个字节的指针。如果不能分配内存
        则返回null,此函数最初用来辅助分配数组内存。
        如果numElements或elementSize为0,那么calloc可能返回空指针。如果calloc无法分配内存就会返回空指针,而且全局变量errno会设置为ENOMEM(内存不足),
        这是POSIX错误码,有的系统上可能没有
    **/
    void maincc()
    {
        //下面两端代码都是为pi分配了20字节,全部包含0
        //int *pi = calloc(5,sizeof(int));

        //int *pi = malloc(5*sizeof(int));
        //memset(pi,0,5*sizeof(int));

        /**
            memset函数会用某个值填充内存块,第一个参数是指向要填充的缓冲区的指针,第二个参数是填缓冲区的值,最后一个参数是要填充的字节数。
            如果内存需要清零可以使用calloc,不过执行calloc可能比执行malloc慢。cfree函数已经没用了。
        */
    }
    /**
        realloc函数
        realloc函数会重新分配内存,原型:void *realloc(void *ptr,size_t size);
        realloc函数返回指向内存块的指针。该函数接受两个参数,第一个参数是指向原内存块的指针,第二个是请求的大小。重新分配的块大小和第一个参数
        引用的块大小不同。返回值是指向重新分配的内存的指针。
        请求的大小可以比当前分配的字节数小或者大。如果比当前分配的小,那么多余的内存会还给堆,不能保证多余的内存会被清空。如果比当前分配的大,
        那么可能的话,就在紧挨着当前分配内存的区域分配新的内存,否则就会在堆的其他区域分配并把旧的内存复制到新区域。
        如果大小是0而指针非空,那么就释放内存。如果无法分配空间,那么原来的内存块就保持不变,不过返回的指针是空指针,且errno会设置为ENMOEM,
    **/
    void maindd()
    {
        /**
            下例使用两个变量为字符串分配内存。一开始分配16个字节,但只用到了前面的13个字节(12个十六进制数字外加null结束字符(0))
        */
        char *string1;
        char *string2;
        string1 = (char*)malloc(16);
        strcpy(string1,"0123456789AB");
        
        /**
            紧接着,用realloc函数指定一个范围更小的内存区域。然后打印这两个变量的地址和内容
        */
        string2 = realloc(string1,8);
        printf("string1 value:%p [%s]\n",string1,string1);
        printf("string2 value:%p [%s]\n",string2,string2);
    }
    /**
        alloca函数和变长数组
        alloca函数(微软为malloca)在函数的栈帧上分配内存。函数返回后会自动释放内存。若低层的运行时系统不基于栈,
        allocal函数会很难实现,所以这个函数时不标准的,如果应用程序需要可移植就尽量避免使用它。
        C99引入了变长数组(VLA),允许函数内部声明和创建其长度由变量决定的数组,比如:
        void compute(int size){
            char * buffer[size];
            ...
        }
        这意味着内存分配在运行时完成,且将内存作为栈帧的一部分来分配。另外,如果数组用到sizeof操作符,也是在运行时而不是编译时执行。
        这么做只会有一点小小的运行时开销。而且一旦函数退出,立即释放内存。因为我们没有用malloc这类函数来创建数组,所以不应该用free函数来
        释放它。alloca函数也不应该返回指向数组所在内存的指针,但是可以解决。
        VLA的长度不能改变,一经分配其长度就固定了。
    **/

    /**
        动态内存分配技术
        1,资源获取即初始化
        资源获取即初始化(Resource Acquisition Is Initialization,RAII)是Bjarne Stroustrup发明的技术,可以用来解决C++中资源的分配和释放。
        即使有异常发生,这种技术也能保证资源的初始化和后续的释放。分配的资源最终总是会得到释放。
        有好几种方法可以在C中使用RAII。GNU编译器提供了非标准的扩展来支持这个特性,通过演示如何在一个函数中分配内存然后释放可以说明这种
        扩展。一旦变量超出作用域会自动触发释放过程。
        GNU的扩展需要用到RAII_VARIABLE宏,它声明一个变量,然后给变量关联如下属性
            1,一个类型。
            2,创建变量时执行的函数。
            3,变量超出作用域时执行的函数。
        这个宏如下所示:
            #define RAII_VARIABLE(vartype,varname,initval,dtor)\
                void _dtor_ ## varname (vartype * v){dtor(*v);}\
                vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)
        在下例中,我们将name变量声明为字符指针。创建它时会执行malloc函数,为其分配32字节。当函数结束时,name超出作用域就会执行free函数:
        void raiiExample(){
            RAII_VARIABLE(char*,name,(char*)malloc(32),free);
            strcpy(name,"RAII Example");
            printf("%s\n",name);
        }
        函数执行后会打印"RAII_Example"字符串。不用GNU扩展也可以达到类似效果。
        2、使用异常处理函数
        另外一种处理内存释放的方法是利用异常处理。尽管异常处理不属于标准C,但如果可以使用它且不考虑移植问题,它会很有用。下面说明利用
        Microsoft Visua Studio版的C语言的方法。
        这里的try块包含任何可能在运行时抛出异常的语句。不管有没有异常抛出,都会执行finally块,因此也一定会执行free函数。
        void exceptionExample(){
            int *pi = NULL;
            __try{
                pi = (int*)malloc(sizeof(int));
                *pi = 5;
                printf("%d\n",*pi);
            }
            __finally{
                free(pi);
            }
        }
    */

    展开全文
  • 在程序的执行期间分配内存时,内存区域中的这个空间称为堆(heap)。还有另一个内存区域,称为栈(stack),其中的空间分配给函数的参数和本地变量。在执行完该函数后,存储参数和本地变量的内存空间会释放。堆中的内存...
  • 如何在程序运行的时候动态给程序分配内存? 文章目录1 动态内存分配的意义1.1 C语言中如何动态申请内存空间1.2 malloc和free的用法1.3 calloc与realloc1.31 calloc和realloc的代码案例分析2 总结 1 动态内存分配...
  • C语言动态内存分配与释放

    千次阅读 2018-02-12 22:00:34
    一,堆内存 1,堆内存特点 堆内存可以存放任意类型的数据,但需要自己申请与释放。 2,堆大小 堆大小,想像中的无穷大,但实际使用中,受限于实际内存的大小和内存是否有连续性。 二,堆内存的申请与释放 ...
  • 所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是...
  • 主要介绍了C语言 动态内存分配的详解及实例的相关资料,需要的朋友可以参考下
  • //二维数组动态分配内存 //为分配n行内存 int **arr = (int **)malloc(sizeof(int)*n); //为每行n列内存 for(i = 0; i ; i++){ arr[i] = (int *)malloc(sizeof(int)*n); } //录入数据 for(i = 0; i ; i++){...
  • 使用动态分配内存的存储空间有局部变量存储,和用户主动申请的内存空间。 局部变量是在函数内部定义的变量,存储在栈数据区当中。局部变量只作用于函数内部,当函数运行结束,就将其分配出去的内存再拿回。栈中的...
  • C语言中的动态内存分配

    千次阅读 2018-10-17 15:34:51
    为什么使用动态内存分配C语言中的一切操作都是基于内存的 变量和数组都是内存的别名,如何分配这些内存由编译器在编译期间决定 定义数组的时候必须指定数组长度 而数组长度是在编译期就必须决定的 需求:...
  • C语言动态内存分配的详解 1.为什么使用动态内存分配 数组在使用的时候可能造成内存浪费,使用动态内存分配可以解决这个问题。 2. malloc和free C函数库提供了两个函数,malloc和free,分别用于执行动态内存分配和...
  • c语言 动态分配存储空间

    千次阅读 2019-10-05 14:56:41
    三种内置函数: ...为指针动态分配内存之后,指针就变成了数组。 返回数组:malloc前面需要强转,且有一个参数;calloc不需要,且有两个参数。 1. malloc: 2. calloc: 3. ralloc: ...
  • 在日常的编程中,我们难免会用到数组,很多时候由于静态开辟数组空间,导致很多空间浪费又或是空间不足,那么这时候就需要用到动态开辟数组内存。下面就介绍这两种初始化数组的方式: 一、静态分配 指定数组长度 //...
  • 用法: (分配类型 * )malloc( 分配元素个数 * sizeof ( 分配类型 ) ) 1.动态一维数组 #include #include int main() { int i,N; scanf("%d",&N); int *num; num = (int *)malloc(N * sizeof(int)); for(i ...
  • C语言动态内存分配上(C语言篇)

    千次阅读 2017-01-08 19:49:59
    静态内存:静态的内存使用的是栈空间内存,不用程序员自己来分配。因为静态变量占用的存储空间对于编译器而言是可预计的,静态内存只需要编程的时候直接声明就可以了。且在开辟空间是就已经确定了所需要开辟的空间...
  • C语言 动态内存分配详解 动态内存分配涉及到堆栈的概念:堆栈是两种数据结构。堆栈都是数据项按序排列的数据结构,只能在一端...除此之外,c语言还允许建立内存动态分配区域,以存放一些临时用的数据,这些数据不必
  • 所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是...
  • C语言数组用到的动态内存分配

    千次阅读 2019-04-25 18:57:43
    动态内存分配 在学习数组的过程中,在输入数组时,原本...所以此时需要用到C语言中的动态内存分配。 通过动态内存分配,则代码可以如此来实现。 #include<stdio.h> int main() { int *a; int i,m,n;...
  • C语言实现动态内存分配
  • C语言动态分配数组

    万次阅读 多人点赞 2018-06-21 12:57:42
    很多人在编写C语言代码的时候很少使用动态数组,不管什么情况下通通使用静态数组的方法来解决,在当初学习C语言的时候我就是一个典型的例子,但是现在发现这是一个相当不好的习惯,甚至可能导致编写的程序出现一些...
  • C语言中手把手教你动态内存分配

    万次阅读 多人点赞 2017-02-06 23:21:07
    C语言中手把手教你动态内存分配动态内存分配常见的内存分配的错误先上一个内存分配的思维导图:便于联想想象,理解: 首先我们介绍一下内存分配的方式:1:在静态存储区域中进行分配 内存在程序编译的时候就已经分配...
  • c语言动态内存分配

    千次阅读 2019-01-03 23:00:21
    这些内存中,有些是自动分配的(栈),有些是在编译时就确定好的(静态区),c语言还可以实现动态的/运行时的内存分配,提高程序的灵活性。 c语言动态内存分配的主要工具是stdlib.h中的malloc()、calloc()和free()...
  • C语言练习题】动态分配内存

    千次阅读 2019-01-10 11:40:00
    编写一个函数,从标准输入读取一列整数,把这些值存储于一个动态分配的数组中并返回这个数组。函数通过观察EOF判断输入列表是否结束。数组的第一个数是数组包含的值的个数,他的后面就是这些整数值   代码 ...
  •  Void *calloc(size_t size) ,包含在库函数 stdlib.h中,作用是在内存的堆区分配一个大小为size的连续空间,如果分配内存成功,函数返回新分配内存的首地址,否则,返回NULL,注意:鉴于上述这点,一般在写程序...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 174,956
精华内容 69,982
关键字:

c语言动态分配内存

c语言 订阅