0

I have read this post about check before calling free(). I want to further confirm through a case.

The following codes are copied from my C++ project (tested, no error/warning). I just want to confirm the right way to check memory allocation and free() in C++.

// part 1: declare 
typedef struct cipher_params_t {
    unsigned char * p1;     
    int p2;                 
}cipher_params_t;

// part 2: allocate memory
cipher_params_t *params = (cipher_params_t*)malloc(sizeof(cipher_params_t));

// part 3: check allocate memory
if (!params) {
    /* Unable to allocate memory on heap*/
    fprintf(stderr, "ERROR: malloc error: %s\n", strerror(errno));
    return errno;
}

// part 4: assign values
unsigned char key[16] = {0x01, 0x02, ..., 0x0f};
params -> p1 = key;
params -> p2 = 1;

// part 5: use params for some function
some_func(params);

// part 6: free params lastly
cleanup1(params);
// cleanup2(params); //another option

void cleanup1 (cipher_params_t *params){
    if(params) free(params)
}

void cleanup2 (cipher_params_t *params){
    if(params!=NULL) free(params)
}

Questions:

  1. In part 3, is this the correct way to check if(!params). Any error is not considered here?

  2. In part 6, I give 2 options - if(params) and if(params!=NULL). Are they same?

  3. In part 1, struct includes pointer(p1) and non-pointer(p2). What is the difference between free a pointer, free a non-pointer, and free a combination of both?

  4. If I use delete[ ] instead of free(). How? and what's the difference?

TJCLARK
  • 489
  • 1
  • 5
  • 19

2 Answers2

4

In part 3, is this the correct way to check if(!params). Any error is not considered here?

Yes this is correct since malloc() returns NULL on failure.

In part 6, I give 2 options - if(params) and if(params!=NULL). Are they same?

Yes, they are the same. But in C++ there is several reasons to use nullptr (a proper type nullptr_t) instead of NULL.

In part 1, struct includes pointer(p1) and non-pointer(p2). What is the difference between free a pointer, free a non-pointer, and free a combination of both?

In fact, you don't and can't release a non-pointer. In your case, you are releasing only one pointer that is a pointer to a cipher_params_t structure.
With malloc() you allocates memory for containing a cipher_params_t whatever the contents is, you just allocate enough space for containing it. And when you free(), you release the allocated memory, no matter what the structure contains.
Please note that malloc() and free() don't call contructors/destructors, neither for the pointed structure, nor for its contents. They are just reserving/allocating memory space.

If I use delete[ ] instead of free(). How? and what's the difference?

Never ever mix malloc()/free(), new/delete and new[]/delete[] because they don't do the same thing. You should read What is the difference between new/delete and malloc/free? for more information.

Fareanor
  • 5,900
  • 2
  • 11
  • 37
  • i read your link. so malloc() cannot be followed by delete/delete[ ]? because one is raw memory, another is destructor. But here https://www.geeksforgeeks.org/delete-in-c/ shows an example of "deleting memory dynamically allocated by malloc". why? – TJCLARK Sep 30 '19 at 11:10
  • @TJCLARK • Mixing them is undefined behavior. On my platform, mixing them terminates the application. – Eljay Sep 30 '19 at 11:22
  • 1
    @TJCLARK This is a perfect example which shows that websites like _geeksforgeeks_ are not trustworthy. Mixing them is undefined behaviour. It can accidentally do what we wanted, or... anything can happen. In fact, the table comparison of the features (in the link I gave) explicitly states why one must never mix them. – Fareanor Sep 30 '19 at 13:09
1

Regarding the question:

In part 1, struct includes pointer(p1) and non-pointer(p2). What is the difference between free a pointer, free a non-pointer, and free a combination of both?

in the example you gave you are deleting a struct from heap mem. This struct has a pointer (assuming 8 bytes) and an int (usually 4 bytes) so you delete this piece of memory (12 bytes) and nothing else.

The memory where the pointer is pointing will remain there, so the key[16] won't be touched. In your example there is a possible issue, as params it's on heap and key is in stack, stack will be deleted when you leave scope but params pointer could still point to it.