0

I thought once you used free() on a memory location, that memory is returned back to memory and if you were to write to that location after it was freed, it would be undefined behavior? This is my teacher's code. Can someone please interpret what he is doing? I don't understand why he is writing to the memory that was just freed. Thankyou!

void initialize(char ***subjects, char***courses, int **CRNs, int *size)
{ 
  int i;

  *subjects = (char**) malloc (INITIAL_COURSE_SIZE * sizeof(char*));
  *courses = (char**) malloc(INITIAL_COURSE_SIZE * sizeof(char*));
  *CRNs = (int*) malloc(INITIAL_COURSE_SIZE * sizeof(int));

      for(i = 0; i < INITIAL_COURSE_SIZE; i++)
      { 
        (*subjects)[i] = (char*) malloc(SUBJECT_SIZE * sizeof(char));
        (*courses)[i] = (char*) malloc(COURSE_SIZE * sizeof(char));
      } // for i

  *size = INITIAL_COURSE_SIZE;
}  // initalize()


void resize(char ***subjects, char***courses, int **CRNs, int *size)
{ 
  int i, *CRNs2, size2 = *size * 2;
  char **subjects2, **courses2;


  subjects2 = (char**) malloc (size2 * sizeof(char*));
  courses2 = (char**) malloc(size2 * sizeof(char*));
  CRNs2 = (int*) malloc(size2 * sizeof(int));

  for(i = 0; i < *size; i++)
  { 
    subjects2[i] = (*subjects)[i];
    courses2[i] = (*courses)[i];
    CRNs2[i] = (*CRNs)[i];
  } // for i

  free(*subjects); //WHY DOES HE FREE THIS??????
  free(*courses);
  free(*CRNs);
  *subjects = subjects2;
  *courses = courses2;
  *CRNs = CRNs2;

  for(; i < size2; i++)
  { 
    (*subjects)[i] = (char*) malloc(SUBJECT_SIZE * sizeof(char));
    (*courses)[i] = (char*) malloc(COURSE_SIZE * sizeof(char));
  } // for i

  *size = size2;
} // resize()

Also, if I were to do:

char **a;
a = (char*)malloc(sizeof(char*) * 100);

Does a point to the the entire array a[]? For example, a[0] and a[1]... would be char pointers. Does a point to the entire block of malloc'd char*'s or just a[0]? Thanks! I really appreciate the help!!

Veger
  • 37,240
  • 11
  • 105
  • 116
Kevin Cheng
  • 115
  • 1
  • 4
  • First ask yourself, what is the typical use case for `resize` ... Then you got the answer. – Basile Starynkevitch Sep 25 '14 at 09:15
  • Haven't read the rest, but your commented frees and writes are not UB because what is freed is the pointed pointer, not the pointer itself. – Medinoc Sep 25 '14 at 09:16
  • 2
    Your teacher should teach people [NOT to cast the return value of `malloc()`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – unwind Sep 25 '14 at 09:36

1 Answers1

1

The resize function basically resizes the given memory blocks, making them twice their size (size2 = *size * 2)

The following is happening:

  • new memory is allocated for the resized blocks
  • the pointers to the subjects, courses and 'CRN's are copied to the new memory
  • the old memory blocks are freed. This does not free() the blocks that the old memory blocks were pointing to! So the new list still points to the valid (not deleted) blocks.
  • the additional part of the new blocks is initialized (by filling in their pointers with newly allocated memory for the subjects and courses data)

Note that all function parameters contain an extra * so the new memory blocks and size are 'returned' (and can be used in the rest of the application).

About your second question on

char **a;
a = (char*)malloc(sizeof(char*) * 100);

a is a list of char*-pointers with length of 100. Only the list is allocated, the items on the list are undefined pointers. To initialized these items as well you could use:

for(int i = 0; i < 100; i++) {
    a[i] = malloc(SIZE_OF_CHAR);
}

Now all items point to a char* with a size of SIZE_OF_CHAR.

Veger
  • 37,240
  • 11
  • 105
  • 116
  • You mean list is an array of 100 elements right? My question was, does a point to the array of 100 elements? or just the first element. Thanks man!! Appreciate it. – Kevin Cheng Sep 25 '14 at 09:22
  • Yes `a` points to the array (which contain undefined pointers, until you define them as shown in my last example code). `a[0]` points to the first array element. – Veger Sep 25 '14 at 09:24
  • Hey Dan, when my teacher does: *subjects = subjects2; Is he assigning the array subjects2 equal to the double pointer subjects or is he just assigning an address of subjects2[0] or what? Thanks. – Kevin Cheng Sep 25 '14 at 09:35
  • @KevinCheng subjects2 is double pointer to char. subjects is triple pointer. that means, subject[i] will be double pointer. Hence *subjects = subjects2 takes the double pointer value from RHS and puts in the subjects[0] (which is also a double pointer) – Kraken Sep 25 '14 at 09:49
  • To add to the explanation of @Kraken, this is used to return the pointer to the newly malloc()-ed array back to the actual function call, so the variables used in the function call are updated (see the 'note' part, after the bulleted list, of my answer) – Veger Sep 25 '14 at 11:29