Search code examples
cpointersfreeheap-memory

List ADT - How to free a struct pointer and its member?


Below is a List ADT,

typedef struct List{
  void **array;

  /* Following members for Housekeeping - Array enhancement*/
  int lastItemPosition;
  int size;
}List;
#define INITIAL_LIST_SIZE 50

createList operation tries to free(*(list->array)) expecting to just free the array of void* but not the objects pointed to each void* because listPointer takes shallow copy of list

List *createList(List *list, Op opType){

  List *listPointer = (List *)malloc(sizeof(List));
  void *accumulator = NULL;
  if(opType == CREATE_NEW_LIST){

    accumulator = malloc(INITIAL_LIST_SIZE*sizeof(void*));
    listPointer->array = &accumulator;

    /* Is it safe to initialise zero to  element of array of void* pointers? */
    listPointer->array = memset(listPointer->array, 0, INITIAL_LIST_SIZE*sizeof(void *));

    listPointer->lastItemPosition = -1;
    listPointer->size = INITIAL_LIST_SIZE;
  }else if(opType == DOUBLE_THE_LIST){

    accumulator = malloc(2*(list->size)*sizeof(void *));
    listPointer->array = &accumulator;

    /* Performing shallow copy, Is deep copy required? */
    listPointer->array = memcpy(listPointer->array, list->array, list->size*sizeof(void*));

    listPointer->lastItemPosition = list->lastItemPosition;;
    listPointer->size = 2*(list->size);

    free(*(list->array)); // How to free  list pointer and its members?

  }else if(opType == HALF_THE_LIST){

    accumulator = malloc(((list->size)/2)*sizeof(void *));
    listPointer->array = &accumulator;

    /* Performing shallow copy, Is deep copy required? */
    listPointer->array = memcpy(listPointer->array, list->array, (list->size/2)*sizeof(void *));
    listPointer->lastItemPosition = list->lastItemPosition;
    listPointer->size = (list->size)/2;

    free(*(list->array)); // How to free  list pointer and its members?
  }

  return listPointer;

}

following list operations are performed List,

void insertItem(List *, void *newItem);
void deleteItem(List *, int listIndex);

User access,

/* main.c */

#include"list.h"

int main(void){
  List *arrayList = createList((List *)NULL, CREATE_NEW_LIST);


  if (arrayList == (List *)NULL){
    fprintf(stderr, "Unable to createList() \n");
    exit(1); //Nothing else to do without arrayList
  }

  /* Objects should be on heap */
  int *object = malloc(sizeof(int));

  *object = 650;


  insertItem(arrayList, object);
}

Question:

Can you please clarify, what does free(*(list->array)) does in my code?


Solution

  • The following code snipped should do the job:

    else if(opType == DOUBLE_THE_LIST){
    
        listPointer->array = realloc(listPointer->array, 2*(list->size)*sizeof(void *));
    
        listPointer->lastItemPosition = list->lastItemPosition;;
        listPointer->size = 2*(list->size);
    
        // do not free any more: free(*(list->array)); // How to free  list pointer and its members?
    }