Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly check the size passed to malloc() calloc() realloc() as well as their return value?

If I have understood correctly, it is also important to check that the desired space passed to malloc(), calloc() or realloc() does not exceed the SIZE_MAX constant after the multiplication with the sizeof(desired_type). In order to make sure that does not happen I started to do something like this in my codes:

#define MAX_CHAIN (50)


#ifndef SIZE_MAX
#define SIZE_MAX (~(size_t)0)
#endif

int main(int argc, char const *argv[]){

    char **parsed_string;

    if(MAX_CHAIN > SIZE_MAX/sizeof(char*) || 
    (parsed_string=(char**)malloc(MAX_CHAIN * sizeof(char*)))==NULL){
        printf("%s\n", "Error, cannot allocate memory");
        exit(1);
    }

    /*Otherwise pointer is valid and the execution continues*/


}

So it basically checks for two things:

  1. That the requested memory is not bigger that SIZE_MAX
  2. That the pointer returned by malloc() is valid.

My questions are: Is it a correct to do these checks? Is this considered as good practice or should I use something else instead? Also, can someone explain why the allocation is limited by SIZE_MAX?

like image 709
tyrana4 Avatar asked Dec 06 '13 14:12

tyrana4


1 Answers

It is correct to do the checks, some would say pedantic. Some thoughts

#include <stdint.h>
...
// MAX_CHAIN > SIZE_MAX/sizeof(char*)
MAX_CHAIN > (SIZE_MAX - sizeof(char*) +1)/sizeof(char*)
// This deals with SIZE_MAX/sizeof(char*) rounding toward 0

A return value of NULL is valid if memory allocation size is 0.

Watch for attempted negative memory allocation requests as many requests are formed with int (signed) even though the request takes size_t (unsigned).


Memory allocation is limited to SIZE_MAX as in typical systems cannot allocate (size_t)-1 or any where new that. Look at the C standard definition of RSZIE_MAX which is closely related to your concerns.

C11dr §K.3.4 3
Extremely large object sizes are frequently a sign that an object’s size was calculated incorrectly. For example, negative numbers appear as very large positive numbers when converted to an unsigned type like size_t. Also, some implementations do not support objects as large as the maximum value that can be represented by type size_t.

like image 192
chux - Reinstate Monica Avatar answered Oct 15 '22 05:10

chux - Reinstate Monica