I’m a bit overwhelmed at this line specifically:
Entry** newHeap = (Entry**)malloc(sizeof(Entry*) * newHeapLength);
in this code:
/**
* Expands the heap array of the given priority queue by
* replacing it with another that is double its size.
*
* @param pq the priority queue whose heap is to be doubled in size
* return 1 for successful expansion or an error code:
*/
int expandHeap (PriorityQueue *pq)
{
int returnCode = 1;
int newHeapLength = pq->heapLength * 2;
Entry** newHeap = (Entry**)malloc(sizeof(Entry*) * newHeapLength);
if (newHeap != NULL)
{
int index;
for (index = 0; index < pq->heapLength; index++)
{
newHeap[index] = pq->heap[index];
}
free(pq->heap);
pq->heap = newHeap;
pq->heapLength = newHeapLength;
}
else
{
returnCode = -1; // TODO: make meaningful error codes
}
return returnCode;
}
It just allocates an array for you, at run-time. Usually the size of array must be specified at compile-time. But here it is specified at run-time, it’s
newHeapLength. Each entry (“cell”) in that array must be capable of storing a value of typeEntry*in it. In C, arrays are contiguous, so the total size of the array, in bytes, is just a product of the two numbers:sizeof(Entry*) * newHeapLength. NownewHeapcan be used to address this array in a usual manner: e.g.newHeap[8]. Of course, if8 >= newHeapLength, this would be accessing past the allocated area, which is bad.For array storing 10
ints,int ia[10];, the type ofiaisint *(correction: almost. but we can pretend that it is, for the purposes of this explanation). Here, similarly, for array storing values of typeEntry*, the type is(Entry*)*. Simple. 🙂And of course you must cast the return value of
mallocto your type, to be able to address that array with it.mallocby itself returns an address asvoid*. Meaning. the size of memory cell which it points to, is proclaimed unknown. When we say thatiais of typeint*, what we actually saying is that memory cell pointed to by it has size ofsizeof(int). So when we writeia[3], it is actually translated into*(ia+3)which is actually*(int*)(void*)( (unsigned int)(void*)ia + 3*sizeof(int) ). In other words, the compiler just addssizeof(int)three times to the starting address, thus “hopping over” threesizeof(int)-wide cells of memory. And fornewHeap[8]it will just “hop” over 8sizeof(Entry*)-wide memory cells, to get the address of the 9-th entry in that array (counting from 1).Also, see hashed array tree for an alternative to the geometric expansion, which is what that code is doing.