Reputation: 78
This C program reads a file with a word per line. I'd like to count the unique words of the file and store it in totalwords, which is passed by reference from the caller function. The program creates an array of strings to store the words that haven been read already. There is another function, quite simple, that checks if a word is already contained in the array of strings, called isContained(), please see at the end of this post. All seems to work OK, and I even checked that the words are consistently stored in the array as unique words. However, when freeing the array the error ""A heap has been corrupted" raises and the program crashes. Sorry if this a newbie question, but I double checked and I cannot find where the error is.
Thanks a lot in advance
Corrections made after comments (sorry, I had to clean up some parts of the original code for posting the example): @Some programmer dude, @ryyker, @kiran biradar, @mlp: I deleted the duplicated declaration of line and added the free(line) at the end. I also reserved space for the string termination. numrecords has been deleted (it was part of the original code deleted for clarification).I'm using Visual Studio 2019, no error arises in debug mode, just 4 warnings. Maybe I'm doing something wrong. Deleted sizeof(char).
Thank you all. I checked again. It was due to another malloc for a string without the additional termination char. Problem solved. Thank you very much!
int fileProcessing(char* file_in, int* totalwords) {
FILE* streamVec;
char* line = malloc(200);
int i=0;
int numberoflines=1000;
char** currentList = malloc(numberoflines* sizeof(char*));
int linelength = 500; //arbitrary value to assure that lines are read completely
streamVec = fopen(file_in, "r");
if (streamVec == NULL) {
printf("*** ERROR: Could not open file: %s\n", file_in);
return 1;
}
*totalwords = 0;
while (fgets(line, linelength, streamVec) != NULL) { //New line read from the file
if ( ! isContained(line, currentList, *totalwords)){ //check if the word is already in the list
currentList[*totalwords] = malloc(strlen(line) * (sizeof(char)+1));
strcpy(currentList[*totalwords], line);
(*totalwords)++;
}
} //End of the read loop
fclose(streamVec);
for (i = 0; i < *totalwords; i++) {
printf("%i %s\n", i, currentList[i]);
free(currentList[i]);
}
free(currentList);
}
int isContained(char* mystring, char** arrayofstring, int arraylength) {
int i;
for (i = 0; i < arraylength; i++) {
if (strcmp(arrayofstring[i], mystring) == 0) {
return 1;
}
}
return 0;
}
Upvotes: 1
Views: 127
Reputation: 238
currentList[*totalwords] = malloc(strlen(line) * (sizeof(char)+1));
This line is incorrect. It should be:
currentList[*totalwords] = malloc((strlen(line) + 1) * sizeof(char));
in order to add the extra byte for the null-termination.
Upvotes: 1
Reputation: 23218
The code you posted compiles, but fails at run-time. The debugger annotated and located the first failure to this location:
memory allocation seems to be the culprit.
Following are a few suggestions, and links to a code snippet or two that may help with the following suggestions.
Problem statement:
List of tasks:
isContained()
function.Some suggested posts for reference:
Get count of words from file. (This can be adapted to get longest word from file.)
Create storage arrays.
Sort original array. (using qsort()
) (Again, optional step.)
Upvotes: 3