So in class we have to create a code that gets word from file, ignores punctuation and prints out the words. Not only that but it has to ignore copies of the same word, but keep track of which words repeat and add its count to a parallel array.But I keep having crashes towards end of program am I deleting incorrectly?
#include <fstream>
#include <iostream>
#include <cstring>
using std::cout;
using std::cin;
using std::endl;
using std::ifstream;
int GetCount(char filename[50]);
int main()
{
char filename[50] = "b.txt";
int choice = 0;
cout << "Input the file name: ";
//cin >> filename;
int numberOfWords = GetCount(filename);
cout << endl << numberOfWords << endl;
ifstream fileRead;
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
fileRead.open(filename);
if (!fileRead.is_open())
{
std::cerr << "\n Error opening file\n";
}
else
{
//Buffers to get words from file
char buffer[1000];
char bufferBuffer[1000];
I declare the arrays here that are causing the problem for deletion
//Array of pointers to words
char ** cStringArray = new char *[numberOfWords];
*cStringArray = nullptr;
int add = 1; //Integer in case a word is repeated not to add
//Parrallel Array to integers
int * intPtr = new int;
*intPtr = 0;
//Pointers used to check for repeated words
int * startIntPtr = intPtr;
int * checkIntPtr = startIntPtr;
char ** startCStringArray = cStringArray;
char ** checkCStringArray = cStringArray;
//Index of Current Word
int indexOfWord = 0;
//Variables for character check
int i = 0;
int k = 0;
//Loop to get words from file
while (fileRead >> buffer)
{
//Add Word
add = 1;
//Copy only alpha characters
i = 0;
k = 0;
while (buffer[k] != '\0')
{
if (isalpha(buffer[k]))
{
bufferBuffer[i] = buffer[k];
i++;
}
k++;
}
bufferBuffer[i] = '\0';
strcpy(buffer, bufferBuffer);
//Actually set it in array
*cStringArray = new char[strlen(buffer) + 1];
strcpy(*cStringArray, buffer);
//Compare Against all other cstrings
for (int ii = 0; ii < indexOfWord; ii++)
{
if (strcmp(*checkCStringArray, buffer) == 0)
{
*checkIntPtr += 1;
add = 0;
}
checkCStringArray++;
checkIntPtr++;
}
//Reset Checks
checkIntPtr = startIntPtr;
checkCStringArray = startCStringArray;
//Move onto next space of cStringArray
if (add == 1)
{
cStringArray++;
*cStringArray = nullptr;
//Add one to index
indexOfWord += 1;
//Add one to intPtr
*intPtr += 1;
intPtr++;
*intPtr = 0;
}
else
{
*cStringArray = nullptr;
*intPtr = 0;
}
}
cStringArray = startCStringArray;
for (int i = 0; i < indexOfWord; i++)
{
cout << *cStringArray << endl;
cStringArray++;
}
cStringArray = startCStringArray;
intPtr = startIntPtr;
for (int i = 0; i < indexOfWord + 1; i++)
{
cStringArray[i] = nullptr;
delete[] cStringArray[i];
}
cStringArray = startCStringArray;
Breaks at this line
delete [] cStringArray;
/*delete[] intPtr;*/
}
return 0;
}
Every new
must be paired with a delete
. Let's check, shall we?
char ** cStringArray = new char *[numberOfWords];
pairs up with
delete [] cStringArray;
Groovy.
*cStringArray = new char[strlen(buffer) + 1];
pairs up with
delete[] cStringArray[i];
that all looks good.
Except...
Let's take a look at that last one with a bit more context.
for (int i = 0; i < indexOfWord + 1; i++)
{
cStringArray[i] = nullptr;
delete[] cStringArray[i];
}
Hmmmm. Set pointer to nullptr
. Delete nullptr
. The program has lost the pointer and leaked the memory before deleting it.
Not so good with a closer look and less noise surrounding it.
Note this is only looking at the deletion. There may be other problems in the code I haven't looked at. At first glance, it seems overly complex. This is why the Minimal, Complete, and Verifiable example is so useful. If you cut all the unnecessary stuff away, it makes the mistakes stand out better.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.