Refine the way I do malloc and free - c
I wrote this code that compiles on Solaris gcc
it works fine too for smaller inputs and I get the output I intend.
However, with larger inputs, I get segmentation faults, sometimes at places I do malloc and sometimes at places I do free. I am not asking for you to debug, could you take a look and possibly tell me if there is something royally wrong with the way I do malloc and free on items? I believe the code is corrputing the heap, but I am having a hard time figuring where. This is for my academic assignment and I cannot run tools like valgrind on the university machine.
I am new to C, so the code can be much better, I know.I still have to refine a lot of stuff, like re-use variables etc etc, which I haven't done yet.
We have a limit on a message size, so I am posting just the main and the two structures used.
struct QueueElement
{
char *path_Name;
char fileType;
int index;
struct QueueElement* next;
};
struct Queue
{
struct QueueElement* head;
struct QueueElement* tail;
};
struct DirNameSlotNumberMapping
{
char *AbsoluteDirPath;
char *AbsoluteParentDirPath;
char *DirName;
int nSlotNumberOfDir;
int nSlotNumberofDot;
};
struct Stage3ADisplay
{
int nSlot;
char *Item;
char *Type;
char *AbsoluteDirPath;
char *AttributesMDHex;
char *ContentsMDHex;
int nIndex;
unsigned char attributesMD[16];
unsigned char contentsMD[16];
};
struct DirNameSlotNumberMapping **DirDataForIndex = NULL; //create structure.
struct Stage3ADisplay **Stage3ADisplayVar = NULL; //create structure.
int nDirectoriesCounter = 0;
int nStage3ARowsCounter = 0;
int main(void)
{
char *pathName,*pathName2,*pathName3;
int nMatchesFound = 0;
char *oldPathName;
char *newPathNameStore;
struct Queue* bfsQueue = NULL;
struct QueueElement* givenPath = NULL;
enum skbool boolHelper1 = skfalse;
int exit = 0;
struct Stage3ADisplay **oldSnapshot = NULL; //create structure.
struct Stage3ADisplay **newSnapshot = NULL;
struct Stage3ADisplay **TableT1FromPDF = NULL;
struct Stage3ADisplay **TableT2FromPDF = NULL;
int nTableT1FromPDFCounter = 0;
int nTableT2FromPDFCounter = 0;
int nOldSnapshotCounter = 0;
int nNewSnapshotCounter = 0;
int *Table1ArrayChangeTracker = NULL;
int *Table2ArrayChangeTracker = NULL;
struct DirNameSlotNumberMapping **DirDataForOldIndex = NULL; //create structure.
struct DirNameSlotNumberMapping **DirDataForNewIndex = NULL; //create structure.
int nDirectoriesCounterOld = 0;
int nDirectoriesCounterNew = 0;
int nIterator1 = 0,nIterator2 = 0, nIterator3 = 0,nIterator4 = 0;
int nIterator5 = 0,nIterator6 = 0,nIterator7 = 0;
int nIterator8 = 0,nIterator9 = 0,nIterator10 = 0,nIterator11 = 0;
int nIterator15 = 0, nIterator16 = 0, nIterator17 = 0;
do
{
switch (menu())
{
case 2:
printf ( "Please enter the path under which the directory is present\n" );
pathName = malloc(300*sizeof(char));
scanf("%s",pathName);
printf ( "Please enter the name of the directory\n" );
pathName2 = malloc(300*sizeof(char));
scanf("%s",pathName2);
pathName3 = malloc(strlen(pathName) + strlen(pathName2) + 1 + 1);
strcpy(pathName3,pathName);
strcat(pathName3,"/");
strcat(pathName3,pathName2);
printf ( "Please enter the filename of the earlier snap shot file\n" );
oldPathName = malloc(300*sizeof(char));
scanf("%s",oldPathName);
boolHelper1 = CheckMD5FileAndDirectoryNameSame(pathName3,oldPathName);
if(boolHelper1 == skfalse)
{
printf("\n");
printf("The snapshot file is not for this directory\n");
printf("\n");
break;
}
else
{
printf("\n");
printf("Snapshot file and Directory Name Match\n");
printf("\n");
//write code to generate snapshot for the directory given here.
bfsQueue = Queue_New();
givenPath = malloc(1*sizeof(*givenPath));
givenPath->path_Name = pathName3;
Queue_Add_Element(bfsQueue, givenPath);
//make bfsTraverse return the name of the log file created.
//this file name can be passed on as a parameter to the
//function that compares the given log file and the newly generated log file
char * newPathName = bfsTraverse(bfsQueue);
newPathNameStore = strdup(newPathName);
Queue_Free(bfsQueue);
free(bfsQueue);
printf("\n");
bfsQueue = NULL;
free(pathName);
pathName = NULL;
//get the data of the two files into two structures.
//we'll compare the two structures.
//reading data of old snapshot into structure 1
FILE* p = NULL;
p = fopen(oldPathName, "r");
if (p != NULL )
{
fscanf(p, "%*[^\n]%*c"); //the first line is the directory name, ignore it.
char text[200];
while(fgets(text, sizeof text, p))
{
//found new item in the file
oldSnapshot = (struct Stage3ADisplay **)realloc(oldSnapshot, (nOldSnapshotCounter + 1) * sizeof(struct Stage3ADisplay *)); //add one record to the structure.
oldSnapshot[nOldSnapshotCounter] = (struct Stage3ADisplay *)malloc(sizeof(struct Stage3ADisplay)); //allocate memory for the new record added.
oldSnapshot[nOldSnapshotCounter]->Item = malloc(500);
oldSnapshot[nOldSnapshotCounter]->Type = malloc(500);
oldSnapshot[nOldSnapshotCounter]->AttributesMDHex = malloc(500);
oldSnapshot[nOldSnapshotCounter]->ContentsMDHex = malloc(500);
char *tempoutput = RemoveExtraSpaces(text,' ');
char * output = Trim_Right( tempoutput,' ');
sscanf(output,"%d %s %s %d %s %s\n",&oldSnapshot[nOldSnapshotCounter]->nSlot, oldSnapshot[nOldSnapshotCounter]->Item,oldSnapshot[nOldSnapshotCounter]->Type,&oldSnapshot[nOldSnapshotCounter]->nIndex,oldSnapshot[nOldSnapshotCounter]->AttributesMDHex,oldSnapshot[nOldSnapshotCounter]->ContentsMDHex);
nOldSnapshotCounter = nOldSnapshotCounter + 1;
}
fclose(p);
}
/*logic to reverse build DirDataForOldIndex */
int nPreviousDot = 0;
for(nIterator1 = 0; nIterator1 < nOldSnapshotCounter; nIterator1++)
{
if(strcmp(oldSnapshot[nIterator1]->Item,".") == 0)
{
nPreviousDot = oldSnapshot[nIterator1]->nSlot;
nPreviousDot = nPreviousDot - 1;
}
if(strcmp(oldSnapshot[nIterator1]->Item,".") != 0 && strcmp(oldSnapshot[nIterator1]->Item,"..") != 0 && strcmp(oldSnapshot[nIterator1]->Type,"d") ==0)
{
//found a directory, add it to the directory mapper structure.
DirDataForOldIndex = (struct DirNameSlotNumberMapping **)realloc(DirDataForOldIndex, (nDirectoriesCounterOld + 1) * sizeof(struct DirDataForIndex *)); //add one student to the structure.
DirDataForOldIndex[nDirectoriesCounterOld] = (struct DirNameSlotNumberMapping *)malloc(sizeof(struct DirNameSlotNumberMapping)); //allocate memory for the new student added.
if(oldSnapshot[nIterator1]->nIndex == 0)
{
DirDataForOldIndex[nDirectoriesCounterOld]->DirName = strdup(oldSnapshot[nIterator1]->Item);
DirDataForOldIndex[nDirectoriesCounterOld]->AbsoluteDirPath = strdup(pathName3);
DirDataForOldIndex[nDirectoriesCounterOld]->AbsoluteParentDirPath = "NOPARENT";
DirDataForOldIndex[nDirectoriesCounterOld]->nSlotNumberOfDir = oldSnapshot[nIterator1]->nSlot;
DirDataForOldIndex[nDirectoriesCounterOld]->nSlotNumberofDot = oldSnapshot[nIterator1]->nSlot + 1;
}
else
{
DirDataForOldIndex[nDirectoriesCounterOld]->DirName = strdup(oldSnapshot[nIterator1]->Item);
DirDataForOldIndex[nDirectoriesCounterOld]->nSlotNumberofDot = oldSnapshot[nIterator1]->nIndex;
DirDataForOldIndex[nDirectoriesCounterOld]->nSlotNumberOfDir = oldSnapshot[nIterator1]->nSlot;
//now build the absolute and the parent dir path names.
//using the previous dot variable,get the directory under which we are located.
//get the index number of the previous dot position.
int IndexVar = oldSnapshot[nPreviousDot]->nIndex;
IndexVar = IndexVar - 1;
//get that row's item and slot number, we'll match it
char *ItemName = oldSnapshot[IndexVar]->Item;
int nSlotNumber = oldSnapshot[IndexVar]->nSlot;
//now search in the DirDataForIndex
for(nIterator2 = 0; nIterator2 < nDirectoriesCounterOld; nIterator2++)
{
if(strcmp(DirDataForOldIndex[nIterator2]->DirName,ItemName) == 0 && DirDataForOldIndex[nIterator2]->nSlotNumberOfDir == nSlotNumber)
{
//that row's absolute path is the parent of this.
DirDataForOldIndex[nDirectoriesCounterOld]->AbsoluteParentDirPath = strdup(DirDataForOldIndex[nIterator2]->AbsoluteDirPath);
char* temp = malloc(strlen(DirDataForOldIndex[nDirectoriesCounterOld]->AbsoluteParentDirPath) + strlen(DirDataForOldIndex[nDirectoriesCounterOld]->DirName) + 1 + 1);
strcpy(temp,DirDataForOldIndex[nDirectoriesCounterOld]->AbsoluteParentDirPath);
strcat(temp,"/");
strcat(temp,DirDataForOldIndex[nDirectoriesCounterOld]->DirName);
DirDataForOldIndex[nDirectoriesCounterOld]->AbsoluteDirPath = strdup(temp);
free(temp);
temp = NULL;
}
}
}
nDirectoriesCounterOld = nDirectoriesCounterOld + 1;
}
}
//reading data of new snapshot into structure 2
p = fopen(newPathName, "r");
if (p != NULL )
{
fscanf(p, "%*[^\n]%*c"); //the first line is the directory name, ignore it.
char text[200];
while(fgets(text, sizeof text, p))
{
//found new item in the file
newSnapshot = (struct Stage3ADisplay **)realloc(newSnapshot, (nNewSnapshotCounter + 1) * sizeof(struct Stage3ADisplay *)); //add one record to the structure.
newSnapshot[nNewSnapshotCounter] = (struct Stage3ADisplay *)malloc(sizeof(struct Stage3ADisplay)); //allocate memory for the new record added.
newSnapshot[nNewSnapshotCounter]->Item = malloc(500);
newSnapshot[nNewSnapshotCounter]->Type = malloc(500);
newSnapshot[nNewSnapshotCounter]->AttributesMDHex = malloc(500);
newSnapshot[nNewSnapshotCounter]->ContentsMDHex = malloc(500);
char * output = Trim_Right(RemoveExtraSpaces(text,' '),' ');
sscanf(output,"%d %s %s %d %s %s\n",&newSnapshot[nNewSnapshotCounter]->nSlot, newSnapshot[nNewSnapshotCounter]->Item,newSnapshot[nNewSnapshotCounter]->Type,&newSnapshot[nNewSnapshotCounter]->nIndex,newSnapshot[nNewSnapshotCounter]->AttributesMDHex,newSnapshot[nNewSnapshotCounter]->ContentsMDHex);
nNewSnapshotCounter = nNewSnapshotCounter + 1;
}
fclose(p);
}
/*logic to reverse build DirDataForNewIndex */
nPreviousDot = 0;
for(nIterator1 = 0; nIterator1 < nNewSnapshotCounter; nIterator1++)
{
if(strcmp(newSnapshot[nIterator1]->Item,".") == 0)
{
nPreviousDot = newSnapshot[nIterator1]->nSlot;
nPreviousDot = nPreviousDot - 1;
}
if(strcmp(newSnapshot[nIterator1]->Item,".") != 0 && strcmp(newSnapshot[nIterator1]->Item,"..") != 0 && strcmp(newSnapshot[nIterator1]->Type,"d") ==0)
{
//found a directory, add it to the directory mapper structure.
DirDataForNewIndex = (struct DirNameSlotNumberMapping **)realloc(DirDataForNewIndex, (nDirectoriesCounterNew + 1) * sizeof(struct DirDataForIndex *)); //add one student to the structure.
DirDataForNewIndex[nDirectoriesCounterNew] = (struct DirNameSlotNumberMapping *)malloc(sizeof(struct DirNameSlotNumberMapping)); //allocate memory for the new student added.
if(newSnapshot[nIterator1]->nIndex == 0)
{
DirDataForNewIndex[nDirectoriesCounterNew]->DirName = strdup(newSnapshot[nIterator1]->Item);
DirDataForNewIndex[nDirectoriesCounterNew]->AbsoluteDirPath = strdup(pathName3);
DirDataForNewIndex[nDirectoriesCounterNew]->AbsoluteParentDirPath = "NOPARENT";
DirDataForNewIndex[nDirectoriesCounterNew]->nSlotNumberOfDir = newSnapshot[nIterator1]->nSlot;
DirDataForNewIndex[nDirectoriesCounterNew]->nSlotNumberofDot = newSnapshot[nIterator1]->nSlot + 1;
}
else
{
DirDataForNewIndex[nDirectoriesCounterNew]->DirName = strdup(newSnapshot[nIterator1]->Item);
DirDataForNewIndex[nDirectoriesCounterNew]->nSlotNumberofDot = newSnapshot[nIterator1]->nIndex;
DirDataForNewIndex[nDirectoriesCounterNew]->nSlotNumberOfDir = newSnapshot[nIterator1]->nSlot;
//now build the absolute and the parent dir path names.
//using the previous dot variable,get the directory under which we are located.
//get the index number of the previous dot position.
int IndexVar = newSnapshot[nPreviousDot]->nIndex;
IndexVar = IndexVar - 1;
//get that row's item and slot number, we'll match it
char *ItemName = newSnapshot[IndexVar]->Item;
int nSlotNumber = newSnapshot[IndexVar]->nSlot;
//now search in the DirDataFornewIndex
for(nIterator2 = 0; nIterator2 < nDirectoriesCounterNew; nIterator2++)
{
if(strcmp(DirDataForNewIndex[nIterator2]->DirName,ItemName) == 0 && DirDataForNewIndex[nIterator2]->nSlotNumberOfDir == nSlotNumber)
{
//that row's absolute path is the parent of this.
DirDataForNewIndex[nDirectoriesCounterNew]->AbsoluteParentDirPath = strdup(DirDataForNewIndex[nIterator2]->AbsoluteDirPath);
char* temp = malloc(strlen(DirDataForNewIndex[nDirectoriesCounterNew]->AbsoluteParentDirPath) + strlen(DirDataForNewIndex[nDirectoriesCounterNew]->DirName) + 1 + 1);
strcpy(temp,DirDataForNewIndex[nDirectoriesCounterNew]->AbsoluteParentDirPath);
strcat(temp,"/");
strcat(temp,DirDataForNewIndex[nDirectoriesCounterNew]->DirName);
DirDataForNewIndex[nDirectoriesCounterNew]->AbsoluteDirPath = strdup(temp);
free(temp);
temp = NULL;
}
}
}
nDirectoriesCounterNew = nDirectoriesCounterNew + 1;
}
}
//now we have reverse built DirDataForOldIndex and DirDataForNewIndex.
Table1ArrayChangeTracker = realloc(Table1ArrayChangeTracker,(nDirectoriesCounterOld + 1)*sizeof(int));
Table2ArrayChangeTracker = realloc(Table2ArrayChangeTracker,(nDirectoriesCounterNew + 1)*sizeof(int));
for(nIterator4 = 0; nIterator4 < nDirectoriesCounterOld; nIterator4++)
{
Table1ArrayChangeTracker[nIterator4] = -1; //initialize to -1
}
for(nIterator4 = 0; nIterator4 < nDirectoriesCounterNew; nIterator4++)
{
Table2ArrayChangeTracker[nIterator4] = -1; //initialize to -1
}
//get blocks one by one from the nDirectoriesCounterOld
for(nIterator4 = 0; nIterator4 < nDirectoriesCounterOld; nIterator4++)
{
char *absoluteDirectoryPath = DirDataForOldIndex[nIterator4]->AbsoluteDirPath;
int dot = DirDataForOldIndex[nIterator4]->nSlotNumberofDot;
int nexthighestdot = 0;
if(nIterator4 == nDirectoriesCounterOld - 1)
{
nexthighestdot = nOldSnapshotCounter;
nexthighestdot = nexthighestdot - 1;
}
else
{
nexthighestdot = DirDataForOldIndex[nIterator4 + 1]->nSlotNumberofDot;
nexthighestdot = nexthighestdot - 1;
nexthighestdot = nexthighestdot - 1;
}
//now, we have a block from dot to nexthighestdot.
//for referenceing the oldSnapshot
dot = dot - 1;
for(nIterator7 = dot; nIterator7 <= nexthighestdot;nIterator7++)
{
TableT1FromPDF = (struct Stage3ADisplay **)realloc(TableT1FromPDF, (nTableT1FromPDFCounter + 1) * sizeof(struct Stage3ADisplay *)); //add one record to the structure.
TableT1FromPDF[nTableT1FromPDFCounter] = (struct Stage3ADisplay *)malloc(sizeof(struct Stage3ADisplay)); //allocate memory for the new record added.
TableT1FromPDF[nTableT1FromPDFCounter]->nSlot = oldSnapshot[nIterator7]->nSlot;
TableT1FromPDF[nTableT1FromPDFCounter]->Item = malloc(strlen(oldSnapshot[nIterator7]->Item) + 1);
strcpy(TableT1FromPDF[nTableT1FromPDFCounter]->Item,oldSnapshot[nIterator7]->Item);
TableT1FromPDF[nTableT1FromPDFCounter]->Type = malloc(strlen(oldSnapshot[nIterator7]->Type) + 1);
strcpy(TableT1FromPDF[nTableT1FromPDFCounter]->Type,oldSnapshot[nIterator7]->Type);
TableT1FromPDF[nTableT1FromPDFCounter]->nIndex = oldSnapshot[nIterator7]->nIndex;
TableT1FromPDF[nTableT1FromPDFCounter]->AttributesMDHex = malloc(strlen(oldSnapshot[nIterator7]->AttributesMDHex) + 1);
strcpy(TableT1FromPDF[nTableT1FromPDFCounter]->AttributesMDHex,oldSnapshot[nIterator7]->AttributesMDHex);
TableT1FromPDF[nTableT1FromPDFCounter]->ContentsMDHex = malloc(strlen(oldSnapshot[nIterator7]->ContentsMDHex) + 1);
strcpy(TableT1FromPDF[nTableT1FromPDFCounter]->ContentsMDHex,oldSnapshot[nIterator7]->ContentsMDHex);
nTableT1FromPDFCounter = nTableT1FromPDFCounter + 1;
}
//now search for the same block in the newSnapshot
for(nIterator6 = 0; nIterator6 < nDirectoriesCounterNew; nIterator6++)
{
if(strcmp(absoluteDirectoryPath,DirDataForNewIndex[nIterator6]->AbsoluteDirPath) == 0)
{
//found the corresponding directory in the second block.
int dot2 = DirDataForNewIndex[nIterator6]->nSlotNumberofDot;
int nexthighestdot2 = 0;
if(nIterator6 == nDirectoriesCounterNew - 1)
{
nexthighestdot2 = nOldSnapshotCounter;
nexthighestdot2 = nexthighestdot2 - 1;
}
else
{
nexthighestdot2 = DirDataForNewIndex[nIterator6 + 1]->nSlotNumberofDot;
nexthighestdot2 = nexthighestdot2 - 1;
nexthighestdot2 = nexthighestdot2 - 1;
}
dot2 = dot2 - 1;
for(nIterator9 = dot2;nIterator9 <= nexthighestdot2; nIterator9++)
{
TableT2FromPDF = (struct Stage3ADisplay **)realloc(TableT2FromPDF, (nTableT2FromPDFCounter + 1) * sizeof(struct Stage3ADisplay *)); //add one record to the structure.
TableT2FromPDF[nTableT2FromPDFCounter] = (struct Stage3ADisplay *)malloc(sizeof(struct Stage3ADisplay)); //allocate memory for the new record added.
TableT2FromPDF[nTableT2FromPDFCounter]->nSlot = newSnapshot[nIterator9]->nSlot;
TableT2FromPDF[nTableT2FromPDFCounter]->Item = malloc(strlen(newSnapshot[nIterator9]->Item) + 1);
strcpy(TableT2FromPDF[nTableT2FromPDFCounter]->Item,newSnapshot[nIterator9]->Item);
TableT2FromPDF[nTableT2FromPDFCounter]->Type = malloc(strlen(newSnapshot[nIterator9]->Type) + 1);
strcpy(TableT2FromPDF[nTableT2FromPDFCounter]->Type,newSnapshot[nIterator9]->Type);
TableT2FromPDF[nTableT2FromPDFCounter]->nIndex = newSnapshot[nIterator9]->nIndex;
TableT2FromPDF[nTableT2FromPDFCounter]->AttributesMDHex = malloc(strlen(newSnapshot[nIterator9]->AttributesMDHex) + 1);
strcpy(TableT2FromPDF[nTableT2FromPDFCounter]->AttributesMDHex,newSnapshot[nIterator9]->AttributesMDHex);
TableT2FromPDF[nTableT2FromPDFCounter]->ContentsMDHex = malloc(strlen(newSnapshot[nIterator9]->ContentsMDHex) + 1);
strcpy(TableT2FromPDF[nTableT2FromPDFCounter]->ContentsMDHex,newSnapshot[nIterator9]->ContentsMDHex);
nTableT2FromPDFCounter = nTableT2FromPDFCounter + 1;
}
break;
}
}
//now we have the matching blocks, start comparing
for(nIterator10 = 0; nIterator10 < nTableT1FromPDFCounter; nIterator10++)
{
for(nIterator11 = 0; nIterator11 < nTableT2FromPDFCounter; nIterator11++)
{
enum skbool bAttributesChanged = skfalse;
enum skbool bContentsChanged = skfalse;
if(strcmp(TableT1FromPDF[nIterator10]->Item,TableT2FromPDF[nIterator11]->Item) == 0)
{
//matching element found in both arrays.
//compare attribute digest and message digests.
if(strcmp(TableT1FromPDF[nIterator10]->AttributesMDHex,TableT2FromPDF[nIterator11]->AttributesMDHex) == 0 && strcmp(TableT1FromPDF[nIterator10]->ContentsMDHex,TableT2FromPDF[nIterator11]->ContentsMDHex) == 0)
{
Table1ArrayChangeTracker[TableT1FromPDF[nIterator10]->nSlot - 1] = 1;
Table2ArrayChangeTracker[TableT2FromPDF[nIterator11]->nSlot - 1] = 1;
nMatchesFound++;
}
else
{
Table1ArrayChangeTracker[TableT1FromPDF[nIterator10]->nSlot - 1] = 2;
Table2ArrayChangeTracker[TableT2FromPDF[nIterator11]->nSlot - 1] = 2;
}
}
}
}
//after comparing clear temporary tables.
int nIterator99;
for(nIterator99 = 0; nIterator99 < nTableT1FromPDFCounter; nIterator99++)
{
free(TableT1FromPDF[nIterator99]->Item);
(TableT1FromPDF[nIterator99]->Item) = NULL;
free(TableT1FromPDF[nIterator99]->Type);
TableT1FromPDF[nIterator99]->Type = NULL;
free(TableT1FromPDF[nIterator99]->AttributesMDHex);
TableT1FromPDF[nIterator99]->AttributesMDHex = NULL;
free(TableT1FromPDF[nIterator99]->ContentsMDHex);
TableT1FromPDF[nIterator99]->ContentsMDHex = NULL;
free(TableT1FromPDF[nIterator99]);
TableT1FromPDF[nIterator99] = NULL;
}
for(nIterator99 = 0; nIterator99 < nTableT2FromPDFCounter; nIterator99++)
{
free(TableT2FromPDF[nIterator99]->Item);
TableT2FromPDF[nIterator99]->Item = NULL;
free(TableT2FromPDF[nIterator99]->Type);
TableT2FromPDF[nIterator99]->Type = NULL;
free(TableT2FromPDF[nIterator99]->AttributesMDHex);
TableT2FromPDF[nIterator99]->AttributesMDHex = NULL;
free(TableT2FromPDF[nIterator99]->ContentsMDHex);
TableT2FromPDF[nIterator99]->ContentsMDHex = NULL;
free(TableT2FromPDF[nIterator99]);
TableT2FromPDF[nIterator99] = NULL;
}
free(TableT1FromPDF);
free(TableT2FromPDF);
nTableT1FromPDFCounter = 0;
nTableT2FromPDFCounter = 0;
TableT1FromPDF = NULL;
TableT2FromPDF = NULL;
}
}
nMatchesFound++;
printf("Total matches found is %d\n",nMatchesFound);
nMatchesFound = 0;
free(oldSnapshot);
free(newSnapshot);
free(DirDataForOldIndex);
free(DirDataForNewIndex);
free(pathName3);
free(oldPathName);
free(Table1ArrayChangeTracker);
free(Table2ArrayChangeTracker);
nOldSnapshotCounter = 0;
nNewSnapshotCounter = 0;
nDirectoriesCounterOld = 0;
nDirectoriesCounterNew = 0;
Table1ArrayChangeTracker = NULL;
Table2ArrayChangeTracker = NULL;
oldSnapshot = NULL;
newSnapshot = NULL;
DirDataForOldIndex = NULL;
DirDataForNewIndex = NULL;
pathName3 = NULL;
oldPathName = NULL;
if(newPathNameStore != NULL)
{
printf("Snapshot file with name %s created\n",newPathNameStore);
free(newPathNameStore);
newPathNameStore = NULL;
}
int nIterator66;
for(nIterator66 = 0; nIterator66 < nDirectoriesCounter; nIterator66++)
{
free(DirDataForIndex[nIterator66]);
DirDataForIndex[nIterator66] = NULL;
}
free(DirDataForIndex);
for(nIterator66 = 0; nIterator66 < nStage3ARowsCounter; nIterator66++)
{
free(Stage3ADisplayVar[nIterator66]);
Stage3ADisplayVar[nIterator66]= NULL;
}
free(Stage3ADisplayVar);
nDirectoriesCounter = 0;
nStage3ARowsCounter = 0;
DirDataForIndex = NULL;
Stage3ADisplayVar = NULL;
break;
case 3:
printf ( "Exiting!\n" );
exit = 1;
break;
}
}while(exit == 0);
return 0;
}
One thing I would recommend is checking the status after malloc and before free as in
char *temp = malloc(10);
if(temp == NULL) {
//Malloc failed handle it
}
and
EDIT: This is unnecessary as oath pointed out free(NULL); is a no-op
if(temp != NULL) {
free(temp);
temp = NULL;
}
There are a few malloc(#) places. You should always use a #*sizeof(type) depending on the type you plan to put in. Then always check to make sure you aren't putting more than # of type into the location.
Unrelated, but it is helpful for readability to typedef structs. Usually something like:
typedef struct dataStructure_t {
int a;
int b;
} dataStructure;
If you have dbx available on your machine, it should quickly find where your code is corrupting its memory with its rtc (run time checking) capability. If not, you might use libumem and/or whatchmalloc to do the same.
Related
How do I debug a Segmentation fault when I nothing is wrong before the fault or after?
The particular problem I have is that in my main function, I have added a print statement before and after I call the "bad" function. It always shows the before statement, but never the after statement. I also added a print statement to the end of the "bad" function, and I can see that it runs properly to the very last line of the "bad" function, so it should return normally. After the functions last print and before the main function print, I get the segfault. Any ideas? Here is the code: int main(int argc, char* argv[]) { char myItem[100]; int i = 0; while (i < 100) { scanf("%[^\n]", myItem); i++; if (myItem == EOF) { break; } int c; while ((c = getchar()) != '\n' && c != EOF); //printf("string read in from user typing: %s\n", myItem); printf("i = %d\n", i); emailFilter(myItem); printf("done with email filter in main\n"); //printf("item from this pass is:%s\n\n", myItem); } return 0; } and the "bad" function: void emailFilter(char* mySubject) { printf(" Just entered the emailFilter() .\n"); char * event_holder[5]; //holds five separate char ptrs for (int i = 0; i < 5; i++) { event_holder[i] = ((char*)malloc(100 * sizeof(char*))); } char command_type = parseSubject(mySubject, event_holder); //parses subject line and fills event_holder. returns command type, from parsing //call proper parsing result if (command_type == 'C') { create(event_holder); } else if (command_type == 'X') { change(event_holder); } else if (command_type == 'D') { delete(event_holder); } printf("Leaving emailfilter()...\n"); } and running this code provides me: $: i = 1 Just entered the emailFilter() . C, Meeting ,01/12/2019,15:30,NEB202 Leaving emailfilter()... done with email filter in main i = 2 Just entered the emailFilter() . Leaving emailfilter()... Segmentation fault This shows that I always make it through the function, but still don't return properly. Here is my entire code to reproduce the error. #include <stdio.h> #include <string.h> #include <stdlib.h> struct node { char * event_data[5]; struct node * next; }; struct node *head = NULL; struct node *current = NULL; char* earliest = NULL; char* substring (char* orig, char* dest, int offset, int len) { int input_len = strlen (orig); if (offset + len > input_len) { return NULL; } strncpy (dest, orig + offset, len); //add null char \0 to end char * term = "\0"; strncpy (dest + len, term, 1); return dest; } char * firstItem(char* shortenedSubject) { int i = 0; int currentLength = 0; int currentCharIndex = 0; int eventIndex = 0; char * toReturn = (char*)malloc(100); while ((shortenedSubject[currentLength] != '\0') && (shortenedSubject[currentLength] != ',') )//50 is my safety num to make sure it exits eventually { currentLength++; } if (shortenedSubject[currentLength] == ',') { substring(shortenedSubject, toReturn, 0, currentLength); } return toReturn; } char parseSubject(char* subject,char * eventDataToReturn[5]) //returns "what type of command called, or none" { char toReturn; char * shortenedSubject = (char*)malloc(100); substring(subject,shortenedSubject,9,strlen(subject)-9);//put substring into tempString int currentCharIndex = 0;// well feed into index of substring() int eventIndex = 0; //lets us know which event to fill in int currentLength = 0;//lets us know length of current event int i = 0; //which char in temp string were alooking at char * action = firstItem(shortenedSubject); if (strlen(action) == 1) { if ( action[0] == 'C') { toReturn = 'C'; } else if (action[0] == 'X') { toReturn = 'X'; } else if (action[0] == 'D') { toReturn = 'D'; } else { toReturn = 'N'; //not valid //invalid email command, do nothing } } else { toReturn = 'N'; //not valid //invalid email command, do nothing } char* debug2; while ((shortenedSubject[i] != '\0') && (i <= 50) )//50 is my safety num to make sure it exits eventually { char debugvar = shortenedSubject[i]; currentLength++; if (shortenedSubject[i] == ',') { //eventDataToReturn[i] = substring2(shortenedSubject,currentCharIndex,currentLength); substring(shortenedSubject,eventDataToReturn[eventIndex],currentCharIndex,currentLength-1); debug2 = eventDataToReturn[eventIndex]; currentCharIndex= i +1; eventIndex++; currentLength = 0; //i++; } i++; } substring(shortenedSubject,eventDataToReturn[4],currentCharIndex,currentLength); return toReturn; } void printEventData(char* my_event_data[]) { //printf("\nPrinting event data...\n"); for (int i = 1; i < 4; i++) { printf("%s,",my_event_data[i]); } //print last entry, no comma printf("%s",my_event_data[4]); } void printEventsInorder() { struct node * ptr = head; while (ptr != NULL)//if not empty, check each one and add when ready { printEventData(ptr->event_data); printf("\n"); ptr = ptr->next; } } void insertFront(char* my_event_data[5]) { struct node *link = (struct node*) malloc(sizeof(struct node)); link->next = NULL; for (int i = 0; i < 5; i++) { link->event_data[i] = my_event_data[i]; } head = link; } int isEarlier(char* event_data_L[5], char* event_data_R[5]) {// will be given like 12:30 12:45,turn timeL into timeL1 and timeL2, and time R1 and timeR2 //compare dates for earlier int month_L,day_L,year_L; int month_R,day_R,year_R; char* char_holder; substring(event_data_L[2],char_holder,0,2);//extract first half of time month_L = atoi(char_holder); //convert first half of time to int substring(event_data_L[2],char_holder,3,2);//extract first half of time day_L = atoi(char_holder); //convert first half of time to int substring(event_data_L[2],char_holder,6,4);//extract first half of time year_L = atoi(char_holder); //convert first half of time to int substring(event_data_R[2],char_holder,0,2);//extract first half of time month_R = atoi(char_holder); //convert first half of time to int substring(event_data_R[2],char_holder,3,2);//extract first half of time day_R = atoi(char_holder); //convert first half of time to int substring(event_data_R[2],char_holder,6,4);//extract first half of time year_R = atoi(char_holder); //convert first half of time to int int time_L1,time_L2,time_R1,time_R2; substring(event_data_L[3],char_holder,0,2);//extract first half of time time_L1 = atoi(char_holder); //convert first half of time to int substring(event_data_L[3],char_holder,3,2);//extract second half of time time_L2 = atoi(char_holder); //convert second half of time to int substring(event_data_R[3],char_holder,0,2); time_R1 = atoi(char_holder); substring(event_data_R[3],char_holder,3,2); time_R2 = atoi(char_holder); //convert to 2 ints, first compare left ints, then right ints if(year_L < year_R) { return 1; } else if ( year_L == year_R) { if (month_L < month_L) { return 1; } else if (month_L == month_L) { if (day_L < day_R) { return 1; } else if (day_L == day_R) { if (time_L1 < time_R1) { return 1; } else if (time_L1 == time_R1) { if (time_L2 < time_R2) { return 1; } else if (time_L2 == time_R2) { return 2; } else//else, time is greater { return 3; } } else //left time is greater, return 3 { return 3; } } else { return 3; } } else { return 3; } } else //its left is greater than right so return 3 to show that { return 3; } } void create(char* my_event_data[5]) { //print required sentence char * debugvar2 = my_event_data[3]; if (head == NULL)//if empty calendar, just add it { insertFront(my_event_data); //printf("EARLIEST bc empty list, \n"); printf("C, "); printEventData(my_event_data); printf("\n"); return; } else { struct node *link = (struct node*) malloc(sizeof(struct node)); link->next = NULL; for (int i = 1; i < 5; i++) { link->event_data[i] = my_event_data[i]; } struct node *ptr = head; struct node *prev = NULL; if (ptr->next == NULL) //if this is the last node to check against { if (isEarlier(my_event_data, ptr->event_data) == 1) { //check against it printf("C, "); printEventData(my_event_data); printf("\n"); if (prev != NULL) //if this is first item in linked list... { link->next = head; //assign something before head head = link; //move head to that thing } if (prev != NULL) { prev->next = link; } link->next = ptr; return; } else //else is equal to or later, so tack it on after: { ptr->next = link; } } else { while (ptr->next != NULL)//if not empty, check each one and add when ready { //if next node is later than current, we are done with insertion if (isEarlier(my_event_data,ptr->event_data) == 1) { if (head == ptr) //if earlier than head... insert and print { //printf("earlier than head!"); printf("C, "); printEventData(my_event_data); printf("\n"); link->next = ptr; head = link; } else //if earlier than non head, insert, but dont print { if (prev != NULL) { prev->next = link; } link->next = ptr; } return; } else { prev = ptr; ptr = ptr->next; } } if (isEarlier(my_event_data,ptr->event_data) == 1) //while ptr-> is null now { printf("C, "); printEventData(my_event_data); printf("\n"); if (prev != NULL) { prev->next = link; } link->next = ptr->next; return; } else { prev = link; link = ptr; } } return; } //if it gets here, it is the latest meeting, tack it on the end //prev->ptr = link; } void change(char* my_event_data[5]) { //create a link struct node *ptr = head; while (ptr->next != NULL)//if not empty, check each one and add when ready { //if next node is later than current, we are done with insertion if (*ptr->event_data[1] == *my_event_data[1]) { for (int i = 1; i < 5; i++) { ptr->event_data[i] = my_event_data[i]; } printf("X, "); printEventData(my_event_data); printf("\n"); return; } ptr = ptr->next; } if (*ptr->event_data[1] == *my_event_data[1]) //check final node { for (int i = 0; i < 5; i++) { ptr->event_data[i] = my_event_data[i]; } printf("X, "); printEventData(my_event_data); printf("\n"); return; } printf("event to change not found"); return; //if it gets here, nothing matched the title to change } void delete(char* my_event_data[5]) { struct node *ptr = head; struct node *prev = NULL; while (ptr != NULL)//if not empty, check each one and add when ready { //if next node is later than current, we are done with insertion if ( strcmp( ptr->event_data[1], my_event_data[1] ) == 0) // if title matches, delete it { if (prev != NULL) { prev->next = ptr->next; } if (ptr == head) { head = ptr->next; } free(ptr); printf("D, "); printEventData(my_event_data); printf("\n"); return; } prev = ptr; ptr = ptr->next; } } void emailFilter(char* mySubject) { if (strlen(mySubject) < 9) { return; } char * event_holder[5]; //holds five separate char ptrs for (int i = 0; i < 5; i++) { event_holder[i] = ((char*)malloc(100 * sizeof(char*))); } char command_type = parseSubject(mySubject, event_holder); //parses subject line and fills event_holder. returns command type, from parsing //call proper parsing result if (command_type == 'C') { create(event_holder); } else if (command_type == 'X') { change(event_holder); } else if (command_type == 'D') { delete(event_holder); } } int main(int argc, char* argv[]) { char myItem[100]; int i = 0; while (i < 100) { scanf("%[^\n]", myItem); i++; if ( myItem == EOF ) { break; } int c; while ((c = getchar()) != '\n' && c != EOF); printf("i = %d\n", i); emailFilter(myItem); } return 0; } Also please note that this error happens when I use a txt file as STDIN via the ">" symbol on the command line. Here is the file I use: Subject: C,Meeting ,01/12/2019,15:30,NEB202 Subject: C,Meeting ,01/12/2019,16:30,NEB202 Subject: C,Meeting ,01/12/2019,11:30,NEB202
Having tried to find something to contribute, there's this: The code is dealing with the date/time. Below is the declaration and use of a "destination buffer" into which is copied fragments of the string: int isEarlier(char* event_data_L[5], char* event_data_R[5]) {// will be given like 12:30 12:45 // .... //compare dates for earlier int month_L,day_L,year_L; int month_R,day_R,year_R; char* char_holder; substring(event_data_L[2],char_holder,0,2);//extract first half of time month_L = atoi(char_holder); //convert first half of time to int //... Notice that char_holder isn't pointing anywhere in particular. UB... While it represents a beginner's approach, it is actually painful to see code like this. Below is a more concise version of isEarlier() (untested.) int isEarlier( char *ed_L[5], char *ed_R[5] ) { char l[16], r[16]; memcpy( l + 0, ed_L[2][6],4 ); // YYYY memcpy( l + 4, ed_L[2][0],2 ); // MM memcpy( l + 6, ed_L[2][3],2 ); // DD memcpy( l + 8, ed_L[3][0],2 ); // hh memcpy( l + 10, ed_L[3][3],2 ); // mm memcpy( r + 0, ed_R[2][6],4 ); // YYYY memcpy( r + 4, ed_R[2][0],2 ); // MM memcpy( r + 6, ed_R[2][3],2 ); // DD memcpy( r + 8, ed_R[3][0],2 ); // hh memcpy( r + 10, ed_R[3][3],2 ); // mm int res = memcmp( l, r, 12 ); return res < 0 ? 1 : res == 0 ? 2 : 3; } Note: The sample data provided indicates 2 digits for both month and day, and is ambiguous as to "mm/dd" or "dd/mm" format. The offset values used here come from the OP code. One way to reduce the possibility of bugs in code is to both write less but more capable code, if you can, and to perform "unit testing" on code that you write. Focus on one function at a time and do not use global variables. Another is to become as familiar as you can with the proven capabilities of functions in the standard library. EDIT: Looking at this answer, it occurs to me that this function should, itself, be refactored: void reformatDateTime( char *d, char *s[5] ) { memcpy( d + 0, s[2][6],4 ); // YYYY memcpy( d + 4, s[2][0],2 ); // MM memcpy( d + 6, s[2][3],2 ); // DD memcpy( d + 8, s[3][0],2 ); // hh memcpy( d + 10, s[3][3],2 ); // mm } int isEarlier( char *ed_L[5], char *ed_R[5] ) { char l[16], r[16]; reformatDateTime( l, ed_L ); reformatDateTime( r, ed_R ); int res = memcmp( l, r, 12 ); res = res < 0 ? 1 : res == 0 ? 2 : 3; printf( "isEarlier() '%.12s' vs '%.12s' result %d\n", l, r, res ); // debug return res; }
and I can see that it runs properly You contradict yourself, you say that it sometimes or always seg faults. It's rather unlikely that some C code would crash at the point of leaving a function, since there's no "RAII" and in this case no multi-threading either. A stack corruption could have destroyed the function return address however. The best way of debugging is not so much about focusing on the symptom, as it trying to pinpoint where something goes wrong. You've already done as much, so that's most of the debug effort already done. One way of debugging from there is step #1: stare at the function for one minute. After around 5 seconds: event_holder[i] = ((char*)malloc(100 * sizeof(char*))); Well that's an obvious bug. After some 30 seconds more: wait, who cleans up this memory? The delete function perhaps but why is it then executed conditionally? (Turns out delete doesn't free() memory though.) The function leaks memory, another bug. Then after one full minute we realize that parseSubject does a whole lot of things and we'll need to dig through that one in detail if we want to weed out every possible chance of bugs. And it will take a lot more time to get to the bottom of that. But we already found 2 blatant bugs just by glancing at the code. Fix the bugs, try again, is the problem gone? At another glance there's a bug in main(), myItem == EOF is senseless and shouldn't compile. This suggests that you are compiling with way too lax warning levels or ignoring warnings, either is a very bad thing. What compiler options are recommended for beginners learning C? We might note that extensive use of "magic numbers" make the code hard to read. It is also usually a sure sign of brittle code. Where do these 5 and 9 and so on come from? Use named constants. We will also fairly quickly note the lack of const correctness in something that's only supposed to parse, not change data. And so on. I didn't read the code in detail, but the overall lack of following best practices and 3 bugs found just by brief glances suggests there's a whole lot more bugs in there.
Key value wont print, despite being used to sort data, looking for the reason why?
I am currently a student learning data structures, particularly the hashmap. I have been attempting to print my results at the end of my program through a printf command in the main function. Despite the fact that I use these keys in the previous while loop, I can not get the keys to print in my final part I have tried checking in the insertMap function (seen below) by using a print to indicate whether the key has actually been stored, and It has been, so that doesn't happen to be the error. int main (int argc, const char * argv[]) { /*Write this function*/ const char * filename = argv[1]; struct hashMap ht; char * entWord; int * oldAt; int repAt; int i = 0; FILE * fp = fopen(filename, "r"); initMap(&ht, 100); while(!feof(fp)){ entWord = getWord(fp); /* printf("%s \n", entWord); */ if(!containsKey(&ht,entWord)) insertMap(&ht, entWord, 1); else{ oldAt = atMap(&ht, entWord); repAt = *oldAt; removeKey(&ht, entWord); insertMap(&ht, entWord, repAt+1); } free(entWord); } for(i = 0; i < ht.tableSize; i++){ if(ht.table[i] != NULL){ printf("%s: %d \n",ht.table[i]->key,ht.table[i]->value); } } fclose(fp); return 0; } void insertMap (struct hashMap * ht, KeyType k, ValueType v) { /*write this*/ int idx = stringHash1(k) % ht->tableSize; struct hashLink * hlnk; struct hashLink * plink; assert(ht); if(ht->table[idx] == NULL){ hlnk = (struct hashLink *) malloc(sizeof(struct hashLink)); hlnk->value = v; hlnk->key = k; hlnk->next = NULL; ht->table[idx] = hlnk; ht->count++; } else{ plink = ht->table[idx]; hlnk = (struct hashLink *) malloc(sizeof(struct hashLink)); hlnk->value = v; hlnk->key = k; hlnk->next = plink->next; plink->next = hlnk; ht->count++; } }
My struct is overlapping some data from the previous one (Edit)
Hi guys I'm having a problem with pointers and memory this is my data structure: struct user_node { char *name; struct user_node *next; struct msg_node *msgnext; }; struct msg_node { char *sender; char *receiver; char *title; char *content; struct msg_node *msgnext; }; Each user have a name and a linked list which store messages. I already have the user creation / deletion implemented but I'm having trouble implementing new msg, I'm using this functions: struct msg_node* sendForm(char** res) { // Format msg before sending struct msg_node *temp = (struct msg_node*) malloc(sizeof(struct msg_node)); char *aux = malloc(sizeof(char) * 400); int i; temp->sender = res[1]; temp->receiver = res[2]; temp->title = res[3]; for (i = 4; i < (n_spaces + 1); i++) { if (res[i] != NULL) { strcat(aux, res[i]); strcat(aux, " "); } } temp->content = aux; return temp; } int sendMsg(struct msg_node* msg) { struct user_node* user = user_database; if (user == NULL) { printf("There aren't users on the system.\n"); return -1; } while (user != NULL) { if (strncmp(user->name, msg->receiver, strlen(msg->receiver)) == 0) { msg->msgnext = user->msgnext; user->msgnext = msg; readmsglist(); return 0; } user = user->next; } printf("User '%s' not found on the system.\n", msg->receiver); return -1; } This is actually working if I only input one msg but when I try to implement the second one this is what's happening: Execution: Welcome to the Program> Enter command (h for help):register user User created There are 1 users right now > Enter command (h for help):send RandomUser1 user content1 a b c Receiver -> user Sender -> RandomUser1 Subject -> content1 Content: a b c > Enter command (h for help):send RandomUser2 user content2 d e f Receiver -> user Sender -> RandomUser2 Subject -> content2 Content: d e f Receiver -> user Sender -> RandomUser2 Subject -> content2 Content: a b c and so more... The weirdest part here is that the content is never overlaped but the other parts actually are. Btw Sorry for my previous post that had to much code. Edit: (Data output function) void readmsglist() { // Show the msg of the first user Test Purposes struct msg_node** ptr = &user_database->msgnext; while (*ptr) { printf("Receiver -> %s\n", (*ptr)->receiver); printf("Sender -> %s\n", (*ptr)->sender); printf("Subject -> %s\n", (*ptr)->title); printf("Content:\n %s\n", (*ptr)->content); ptr = &(*ptr)->msgnext; } } Edit2 (More info): First, the function is called here: case 24: //Send messages if (countSpaces(input) > 2) { sendMsg(sendForm(cut(input))); } else { E_Type(); } break; This is the cut function: char** cut(char str[]) { char ** res = NULL; char * p = strtok(str, " "); n_spaces = 0; // Global variable (int) /* split string and append tokens to 'res' */ while (p) { res = realloc(res, sizeof(char*) * ++n_spaces); if (res == NULL) exit(-1); /* memory allocation failed */ res[n_spaces - 1] = p; p = strtok(NULL, " "); } /* realloc one extra element for the last NULL */ res = realloc(res, sizeof(char*) * (n_spaces + 1)); res[n_spaces] = 0; return res; } The input is like -> send :
Edw4d and I had a long discussion and debugging session. The message data is being overwritten by user input because the location of the data in input buffer in each message is being stored in each message node, rather than actually copying the string into a new buffer. This solves the problem: char** cut(char str[]) { char *p = strtok(str, " "); // We don't need the first token. p = strtok(NULL, " "); char **res = calloc(sizeof(char*), 4); /* allocate a buffer full of NULL's*/ if (res == NULL) exit(-1); /* memory allocation failed */ /* split string and append tokens to 'res' */ for (int idx = 0; idx < 3; idx++) { res[idx] = malloc(strlen(p) + 1); strcpy(res[idx], p); p = strtok(NULL, " "); } p[strlen(p)] = ' '; // Put the space back where strtok wrote the null character. res[3] = malloc(strlen(p) + 1); strcpy(res[3], p); return res; } MsgNode* sendForm(char** res) { // Format msg before sending struct msg_node *temp = (struct msg_node*) malloc(sizeof(struct msg_node)); temp->receiver = res[0]; temp->sender = res[1]; temp->title = res[2]; temp->content = res[3]; return temp; }
Segmentation Fault: double free or corruption (fast top)
I've a problem when I run this piece of code: a Segmentation Fault that appears during the free instruction of percorso. I cannot find the problem. void ricerca(char nome[], struct node *radice, char percorso[], struct stringhe **indice) { struct node *punt = radice; int dim = len(percorso); char *prov = NULL; if (dim > 0) { prov = malloc(2 * dim * sizeof(char)); prov[0] = '\0'; strcpy(prov, percorso); free(percorso); //--------------------->here the SegFault } struct stringhe *nuovo = NULL; int i = 0, fine = 0; char *perc_orig = NULL; if (punt != NULL) { if (punt->array != NULL) { dim = len(prov) + len(punt->nome) + 2; percorso = malloc(dim * sizeof(char)); percorso[0] = '\0'; if (prov!=NULL) strcpy(percorso, prov); strcat(percorso, "/"); strcat(percorso, punt->nome); perc_orig = malloc(dim * sizeof(char)); for (i = 0; i < N; i++) { if (punt->array->vet[i] != NULL) { perc_orig[0] = '\0'; strcpy(perc_orig, percorso); ricerca(nome, punt->array->vet[i], perc_orig,indice); } } free(perc_orig); } if (strcmp(nome,punt->nome) == 0) { free(percorso); dim = len(prov) + len(punt->nome) + 2; percorso = malloc(dim * sizeof(char)); inizializza(percorso, dim); if (prov != NULL) strcpy(percorso, prov); strcat(percorso, "/"); strcat(percorso, punt->nome); nuovo = malloc(sizeof(struct stringhe)); nuovo->next = NULL; nuovo->str = malloc(dim * sizeof(char)); inizializza(nuovo->str, dim); strcpy(nuovo->str, percorso); nuovo->next = (*indice); *indice = nuovo; } while (punt->chain != NULL && fine == 0) { ricerca(nome, punt->chain,prov, indice); fine = 1; if (prov!=NULL) free(prov); } } } The len function is like strlen, but the difference is that I've made it myself. the context is: void find(char nome[], struct node *radice) { char *perc = NULL; struct stringhe **inizio = NULL; inizio = malloc(sizeof(struct stringhe*)); *inizio = NULL; int i = 0; for (i = 0; i < N; i++) { if (radice->array->vet[i] != NULL) { perc = NULL; ricerca(nome, radice->array->vet[i], perc, inizio); } } if (*inizio != NULL) { insertion(inizio); stampap(*inizio); } else printf("no\n"); } And the data structures: struct tab { struct node *vet[64]; }; struct node { char nome[255]; int num; int tipo; char *dati; struct tab *array; struct node *chain; };
This is really weird: if (some condition) free(percorso); Later on we have: perc_orig = malloc(dim*sizeof(char)); for(something){ if(something){ ricerca(nome,punt->array->vet[i],perc_orig,indice); } } free(perc_orig); If that if conditions happens, perc_orig will be freed twice. Kaboom. I think your problem is you think that ricerca(..., char percico[], ...) copies percico. It doesn't; it's really ricerca(..., char *percico, ...) so you ended up freeing the memory twice.
the sizing for the char arrays needs to allow for the trailing NUL ('\0') character. ALL fields that are referenced by strcpy() and similar functions need to have ALL source character arrays NUL terminated. The code does not seem to be allocating enough room for those trailing NUL bytes NOR terminating every character array with a NUL char.
Segmentation fault occurs when you initialize a character pointer to NULL and try to point it to a not null value For example, char *a=NULL; a='a'; Will cause segmentation fault. To avoid this you can try to initialize as, char *a; a='a';
Memory leak in a recursive function in c
I need some help with memory leak in my C program. The following function searches a radix trie to find a word with a given number. It allocates some memory in every recursive call and I don't know how to sort it out so that the blocks allocated aren't lost. Please help. char *substring(char *str, int position, int length) { int c = 0; char *sub = malloc(length*(sizeof(char))+1); while (c < length) { sub[c] = str[position + c]; c++; } return sub; } void prev(int w, int start, int end) { char *newWord = ""; bool found = false; void prevRec(struct tNode *t, int w, int start, int end, char *soFar, int prevLength) { if (t != NULL) { char *updatedWord = malloc(strlen(soFar) + strlen(t->word)); strcpy(updatedWord,soFar); strcat(updatedWord,t->word); printf("%s\n", updatedWord); int length = strlen(t->word); if (t->count == w) { found = true; if ((start > -1) && (end <= strlen(updatedWord))) { newWord = updatedWord; } else { newWord = ""; } } else { struct tNode *tmp = t->child; struct tNode *tmp1 = NULL; while ((tmp != NULL) && (!found)) { prevRec(tmp,w,start,end,updatedWord,length); tmp1 = tmp; tmp = tmp->brother; updatedWord = substring(updatedWord, 0, strlen(updatedWord) - prevLength); } } } } prevRec(root,w,start,end,newWord,0); printf("%s\n",newWord); if (strlen(newWord) == 0) printf("ignored"); else { char *tmp = substring(newWord,start,end - start + 1); insert(tmp); free(tmp); }
You must free what you've allocated. In your case you could to sth. like that: replace updatedWord = substring(updatedWord, 0, strlen(updatedWord) - prevLength); by char *sub = substring(updatedWord, 0, strlen(updatedWord) - prevLength); free( updatedWord ); updatedWord = sub; and add another free( updatedWord ); as last line of your if( t != NULL ) block. Besides as #Eregith has already mentioned in his comment, the '+1' for NULL is missing in the length you are allocating. And you should also add some error checking, as malloc() may return NULL