-1

i have a struct such as

typedef struct bignum {
    long number_of_digits;
    char *digit;
} bignum;

and i want to declare an array of type bignum, the array size is going to be changed dynamically , so i used malloc() , realloc() can i shrink the array using realloc() with out memory leakes. sample of shrinking code

if(free_slots == 50)
{
    big_num_Arr =(bignum *) realloc  (big_num_Arr,(capacity-40)*sizeof(bignum));
    free_slots = 10;
    capacity -= 40;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    If the struct has dynamically allocated data, they have to be freed. realloc can’t do that for you – Sami Kuhmonen Mar 20 '18 at 20:49
  • What is `free_slots` and what is `capacity`? – Arndt Jonasson Mar 20 '18 at 20:52
  • Have a look at this thread. https://stackoverflow.com/questions/7078019/using-realloc-to-shrink-the-allocated-memory – Witnessthis Mar 20 '18 at 20:57
  • *"the array size is going to be changed dynamically"* do you mean size of the `bignum` array, or the size of each one's `digit` array? Or both? You should get your bignum functions working perfectly with fixed length arrays, before complicating it. – Weather Vane Mar 20 '18 at 20:59
  • big_num_Arr this array is going to be changed , free_slots and capacity are not important ,,, its all about the first line after the if, – Baraa Natour Mar 20 '18 at 21:20

2 Answers2

1

Assuming the digit pointers point to dynamically-allocated arrays, you need to free them before realloc() deallocates those elements of big_num_Arr.

if(free_slots == 50)
{
    for (int i = 10; i < free_slots; i++) {
        free(big_num_Arr[i].digit);
    }
    big_num_Arr = realloc(big_num_Arr,(capacity-40)*sizeof(bignum));
    free_slots = 10;
    capacity -= 40;
}

Also, see Do I cast the result of malloc?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • "Assuming the digit pointers point to dynamically-allocated arrays," it's dynamically allocated, its actually a string , so to be sure i under stood your answer ,, I deleted 40 elements from the array so , i need to free dynamically allocated fields in those 40 elements? – Baraa Natour Mar 20 '18 at 21:46
  • Yes. Also, ensure that you initialize the pointer to `NULL` in elements that haven't had any digits allocated. – Barmar Mar 20 '18 at 21:48
  • @BaraaNatour to be more precise: you only need to free the allocated memory for the `digit` pointer in the 40 elements you want to "remove" – Pablo Mar 20 '18 at 21:55
0

can i shrink the array using realloc() with out memory leaks (?)

Yes, but not robustly with OP's code. Any reallocaiton, even a shrinking one, may return NULL and that should be checked.

if (free_slots == 50) {
  size_t new_capacity = capacity-40;
  ...
  if (new_capacity > 0) {
    void *new_ptr =  realloc(big_num_Arr, sizeof *big_num_Arr * new_capacity);
    if (new_ptr) {
      big_num_Arr = new_ptr; 
      capacity = new_capacity;
    } else if (new_capacity <= capacity) {
      // perhaps leave values "as is" 
      // big_num_Arr = big_num_Arr; 
      // capacity = capacity;
    } else {
      // allocation failure
      // perhaps leave values "as is", yet return a error
      // big_num_Arr = big_num_Arr; 
      // capacity = capacity;
      return failure;
    }
  } else {
    free(big_num_Arr);
    big_num_Arr = NULL; 
    capacity = 0;
  }
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256