How can I correctly handle malloc failure in C, especially when there is more than one malloc?

前端 未结 6 567
我在风中等你
我在风中等你 2021-02-01 02:49

Suppose this is a part of my code:

 int foo()
 {  
    char *p, *q ;
    if((p = malloc(BUFSIZ)) == NULL) {
        return ERROR_CODE;
    }
    if((q = malloc(B         


        
6条回答
  •  囚心锁ツ
    2021-02-01 03:31

    For large numbers of allocations, I would invest the time in creating a memory manager that keeps track of the allocations. That way, you never have to worry about leaks, regardless of whether or not the function succeeds.

    The general idea is to create a wrapper for malloc that records successful allocations, and then frees them on request. To free memory, you simply pass a special size to the wrapper function. Using a size of 0 to free memory is appropriate if you know that none of your actual allocations will be for 0 sized blocks. Otherwise, you may want to use ~0ULL as the request-to-free size.

    Here's a simple example that allows up to 100 allocations between frees.

    #define FREE_ALL_MEM 0
    
    void *getmem( size_t size )
    {
        static void *blocks[100];
        static int count = 0;
    
        // special size is a request to free all memory blocks
        if ( size == FREE_ALL_MEM )
        {
            for ( int i = 0; i < count; i++ )
                free( blocks[i] );
            count = 0;
            return NULL;
        }
    
        // using a linked list of blocks would allow an unlimited number of blocks
        // or we could use an array that can be expanded with 'realloc'
        // but for this example, we have a fixed size array
        if ( count == 100 )
            return NULL;
    
        // allocate some memory, and save the pointer in the array
        void *result = malloc( size );
        if ( result )
            blocks[count++] = result;
    
        return result;
    }
    
    int foo( void )
    {
        char *p, *q;
    
        if ( (p = getmem(BUFSIZ)) == NULL ) {
            return ERROR_CODE;
        }
        if ( (q = getmem(BUFSIZ)) == NULL ) {
            getmem( FREE_ALL_MEM );
            return ERROR_CODE;
        }
    
        /* Do some other work... */
    
        getmem( FREE_ALL_MEM );
        return SUCCESS_CODE;
    }
    

提交回复
热议问题