So, I am writing a program to manage the heap data structure. I make two allocations of dynamic memory and (I think) I release them correctly when I wrap things.
#include "heapFunctions.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
static element* getArray(int*);
int main(void){
int result=0;
int i,v;
heap myHeap;
myHeap.H = NULL;
int arrayLength;
element* myArray = NULL;
char menuSelection = nextCommand(&i,&v);
while(!(menuSelection == 'S' || menuSelection == 's')){
switch(menuSelection){
case 'c':
case 'C':
if(myHeap.H == NULL)
myHeap = initialize(i);
else{
free(myHeap.H);
myHeap=initialize(i);
}
if(myHeap.H != NULL)
printf("Command Entered %c. Heap Initialized with capacity %d\n", menuSelection, i);
else
printf("Command Entered %c. Heap space not allocated\n", menuSelection);
break;
case 'r':
case 'R':
if(myArray == NULL)
myArray = getArray(&arrayLength);
else{
free(myArray);
myArray = getArray(&arrayLength);
}
result=buildHeap(&myHeap, myArray, arrayLength);
if(result==1)
printf("Command Entered %c. Heap was built with size %d\n", menuSelection, arrayLength);
else if (result == -1)
printf("Command Entered %c. Heap build was unsuccesful\n", menuSelection);
else if (result == -2)
printf("Command Entered %c. Heap capacity can't accomodate array\n", menuSelection);
break;
case 'w':
case 'W':
printf("Command Entered %c. Printing Heap\n", menuSelection);
printHeap(&myHeap);
break;
case 'i':
case 'I':
result = insert(&myHeap, i);
if (result == 1)
printf("Command Entered %c. Heap insert with key %d was succesful\n", menuSelection, i);
else
printf("Command Entered %c. Heap insert was unsuccesful\n", menuSelection);
break;
case 'd':
case 'D':
result = deleteMax(&myHeap);
if (result > 0)
printf("Command Entered %c. Deletion of max heap value %d was succesful\n", menuSelection, result);
break;
case 'k':
case 'K':
result = increaseKey(&myHeap, i, v);
if(result == 1)
printf("Command Entered %c. Key was succesfully increased to %d at index %d\n", menuSelection, v, i);
else if(result == -1)
printf("Command Entered %c. Key increase failed, %d not a valid index\n", menuSelection, i);
else if (result == -2)
printf("Command Entered %c. Key increase failed, %d is not larger than current key\n", menuSelection, v);
else if (result == -3)
printf("Command Entered %c. Key increase failed, Index starts at 1!", menuSelection);
}
menuSelection = nextCommand(&i,&v);
}
printf("You have entered command %c and stopped the program.\n", menuSelection);
free(myArray);
free(myHeap.H);
return 1;
}
static element* getArray(int *Length){
element *arrayKey;
int arrayLength=0;
char inputBuffer[10];
FILE *fp;
fp = fopen("HEAPinput.txt","r");
if (fp == NULL){
fprintf(stderr, "Cannot open input file!!\n");
exit(1);
}
if(fgets(inputBuffer, sizeof(inputBuffer), fp) != NULL){
sscanf(inputBuffer, "%d", &arrayLength);
}
if(arrayLength < 1){
printf("Invalid Array Length\n");
exit(1);
}
arrayKey = (element *) malloc(sizeof(element)*arrayLength);
if(arrayKey == NULL){
printf("Memory for array not allocated\n");
exit(1);
}
int count;
for (count =0; count < arrayLength; count++){
fscanf(fp, "%d", &arrayKey[count].key);
}
*Length = arrayLength;
fclose(fp);
return arrayKey;
}
heap initialize(int capacity){
heap myHeap;
myHeap.size = 0;
myHeap.capacity = capacity;
myHeap.H = (element*) malloc(sizeof(element)*capacity);
return myHeap;
}
int buildHeap(heap *myHeap, element * myArray, int arrayLength){
if(arrayLength > myHeap->capacity)
return -2;
if(myHeap->H == NULL)
return -3;
if(memcpy(myHeap->H, myArray, sizeof(element)*arrayLength) == NULL)
return -1;
myHeap->size=arrayLength;
int count=0;
for(count=(arrayLength/2); count >= 0; count--){
heapify(myHeap, count);
}
return 1;
}
I'm not very sure how this works, I tried just posting code snippets that I thought were mandatory. I only dynamically allocate memory in two places, and I thought I freed them properly before leaving the main one. I don’t see where else I can leak.
I used valgrind and got errors
LEAK SUMMARY:
==4042== definitely lost: 13,546 bytes in 70 blocks
==4042== indirectly lost: 53 bytes in 5 blocks
==4042== possibly lost: 29 bytes in 2 blocks
==4042== still reachable: 33,958 bytes in 53 blocks
( ), ( ). gcc + g++ valgrind -g fulltrace, ??? .
==5804== 3 bytes in 1 blocks are possibly lost in loss record 2 of 97
==5804== at 0x4C2C73C: malloc (vg_replace_malloc.c:270)
==5804== by 0x440137: ??? (in /usr/bin/g++-4.7)
==5804== by 0x43CDEB: ??? (in /usr/bin/g++-4.7)
==5804== by 0x414C80: ??? (in /usr/bin/g++-4.7)
==5804== by 0x41592F: ??? (in /usr/bin/g++-4.7)
==5804== by 0x40296E: ??? (in /usr/bin/g++-4.7)
==5804== by 0x4E5576C: (below main) (libc-start.c:226)
349 (320 direct, 29 indirect) bytes in 2 blocks are definitely lost in loss record 73 of 96
==4098== at 0x4C2C92E: realloc (vg_replace_malloc.c:662)
- , .