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

前端 未结 6 660
我在风中等你
我在风中等你 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:23

    Your code is fine, but for lots of variables, I'd prefer:

    int
    foo()
    {
        char *p = NULL;
        char *q = NULL;
        int ret = 0;
    
        if (NULL == (p = malloc(BUFSIZ)))
        {
            ret = ERROR_CODE;
            goto error;
        }
    
        // possibly do something here
    
        if (NULL == (q = malloc(BUFSIZ)))
        {
            ret = ERROR_CODE;
            goto error;
        }
    
        // insert similar repetitions
    
        // hopefully do something here
    
      error:
        free (p);
        free (q);
        return ret;
    }
    

    Note that freeing NULL is defined as a no-op.

    This avoids n levels of indent for n variables. You can clean up filehandles etc. similarly (though you'll have to put a condition around the close()).

    Now, if you know you can allocate them all at once, then dasblinkenlight has a good answer, but here's another way:

    int
    foo()
    {
        int ret = 0;
        char *p = malloc(BUFSIZ);
        char *q = malloc(BUFSIZ);
        char *r = malloc(BUFSIZ);
        if (!p || !q || !r)
        {
            ret = ERROR_CODE;
            goto exit;
        }
    
        // do something
    
      exit:
        free(p);
        free(q);
        free(r);
        return ret;
    }
    

    Final possibility: if you actually want to exit the program on malloc fail, consider using mallopt's M_CHECK_ACTION option. This makes malloc() faults get checked, and calls abort(), possibly printing a helpful message.

    From the man page:

    NAME

    mallopt - set memory allocation parameters

    SYNOPSIS

      #include 
    
      int mallopt(int param, int value);
    

    DESCRIPTION

    The mallopt() function adjusts parameters that control the behavior of the memory-allocation functions (see malloc(3)). The param argument specifies the parameter to be modified, and value specifies the new value for that parameter.

    The following values can be specified for param:

    M_CHECK_ACTION

    Setting this parameter controls how glibc responds when various kinds of programming errors are detected (e.g., freeing the same pointer twice). The 3 least significant bits (2, 1, and 0) of the value assigned to this parameter determine the glibc behavior, as follows:

    Bit 0: If this bit is set, then print a one-line message on stderr that provides details about the error. The message starts with the string "*** glibc detected ***", followed by the program name, the name of the memory-allocation function in which the error was detected, a brief description of the error, and the memory address where the error was detected.

    Bit 1: If this bit is set, then, after printing any error message specified by bit 0, the program is terminated by calling abort(3). In glibc versions since 2.4, if bit 0 is also set, then, between printing the error message and aborting, the program also prints a stack trace in the manner of backtrace(3), and prints the process's memory mapping in the style of /proc/[pid]/maps (see proc(5)).

    Bit 2: (since glibc 2.4) This bit has an effect only if bit 0 is also set. If this bit is set, then the one-line message describing the error is simplified to contain just the name of the function where the error was detected and the brief description of the error.

提交回复
热议问题