I have an assignment i am trying to write I keep getting this error:
Added: watermellon
Added to dictionary: watermellon
Added: pineapple
Added to dictionary: pineapple
Misspelled word: apple
Misspelled word: banana
Misspelled word: orange
Misspelled word: grape
Misspelled word: watermelon
Misspelled word: pineaple
SimpleVector destroyed.
Misspelled words:
double free or corruption (fasttop)
Aborted (core dumped)
I have checked to remove and dupes, and nothing was doubled up. I’m just not seeing the mistake.
here is my code:
DoublyLinkedBag.cpp
#include "DoublyLinkedBag.h"
#include <iostream>
template<class ItemType>
DoublyLinkedBag<ItemType>::DoublyLinkedBag() : headPtr(nullptr), itemCount(0) {}
template<class ItemType>
DoublyLinkedBag<ItemType>::~DoublyLinkedBag() {
clear();
}
template<class ItemType>
int DoublyLinkedBag<ItemType>::getCurrentSize() const {
return itemCount;
}
template<class ItemType>
bool DoublyLinkedBag<ItemType>::isEmpty() const {
return itemCount == 0;
}
template<class ItemType>
bool DoublyLinkedBag<ItemType>::add(const ItemType& newEntry) {
Node<ItemType>* newNodePtr = new Node<ItemType>(newEntry, headPtr, nullptr);
if (headPtr != nullptr) {
headPtr->setPrev(newNodePtr);
}
headPtr = newNodePtr;
itemCount++;
std::cout << "Added: " << newEntry << std::endl;
return true;
}
template<class ItemType>
bool DoublyLinkedBag<ItemType>::remove(const ItemType& anEntry) {
Node<ItemType>* entryNodePtr = getPointerTo(anEntry);
bool canRemoveItem = !isEmpty() && (entryNodePtr != nullptr);
if (canRemoveItem) {
if (entryNodePtr == headPtr) {
headPtr = headPtr->getNext();
if (headPtr != nullptr) {
headPtr->setPrev(nullptr);
}
} else {
entryNodePtr->getPrev()->setNext(entryNodePtr->getNext());
if (entryNodePtr->getNext() != nullptr) {
entryNodePtr->getNext()->setPrev(entryNodePtr->getPrev());
}
}
delete entryNodePtr;
itemCount--;
}
return canRemoveItem;
}
template<class ItemType>
void DoublyLinkedBag<ItemType>::clear() {
Node<ItemType>* nodeToDeletePtr = headPtr;
while (headPtr != nullptr) {
headPtr = headPtr->getNext();
delete nodeToDeletePtr;
nodeToDeletePtr = headPtr;
}
itemCount = 0;
}
template<class ItemType>
int DoublyLinkedBag<ItemType>::getFrequencyOf(const ItemType& anEntry) const {
int frequency = 0;
Node<ItemType>* curPtr = headPtr;
while (curPtr != nullptr) {
if (anEntry == curPtr->getItem()) {
frequency++;
}
curPtr = curPtr->getNext();
}
return frequency;
}
template<class ItemType>
bool DoublyLinkedBag<ItemType>::contains(const ItemType& anEntry) const {
return (getPointerTo(anEntry) != nullptr);
}
template<class ItemType>
SimpleVector<ItemType> DoublyLinkedBag<ItemType>::toVector() const {
SimpleVector<ItemType> bagContents;
Node<ItemType>* curPtr = headPtr;
while (curPtr != nullptr) {
bagContents.push_back(curPtr->getItem());
curPtr = curPtr->getNext();
}
return bagContents;
}
template<class ItemType>
Node<ItemType>* DoublyLinkedBag<ItemType>::getPointerTo(const ItemType& target) const {
Node<ItemType>* curPtr = headPtr;
while (curPtr != nullptr) {
if (target == curPtr->getItem()) {
return curPtr;
}
curPtr = curPtr->getNext();
}
return nullptr;
}
DoublyLinkedBag.h
#ifndef DOUBLY_LINKED_BAG_H
#define DOUBLY_LINKED_BAG_H
#include "Node.h"
#include "SimpleVector.h"
template<class ItemType>
class DoublyLinkedBag {
private:
Node<ItemType>* headPtr;
int itemCount;
Node<ItemType>* getPointerTo(const ItemType& target) const;
public:
DoublyLinkedBag();
virtual ~DoublyLinkedBag();
int getCurrentSize() const;
bool isEmpty() const;
bool add(const ItemType& newEntry);
bool remove(const ItemType& anEntry);
void clear();
int getFrequencyOf(const ItemType& anEntry) const;
bool contains(const ItemType& anEntry) const;
SimpleVector<ItemType> toVector() const;
};
#include "DoublyLinkedBag.cpp"
#endif // DOUBLY_LINKED_BAG_H
main.cpp
include <iostream>
#include <fstream>
#include <cstring>
#include "DoublyLinkedBag.h"
/**
* @brief Converts a C-style string to lowercase.
*
* @param str The string to convert.
*/
void toLowerCase(char* str) {
for (int i = 0; str[i]; i++) {
str[i] = std::tolower(str[i]);
}
}
/**
* @brief Loads the dictionary from a file into a DoublyLinkedBag.
*
* @param dictionary The DoublyLinkedBag to load the dictionary into.
* @param filename The name of the dictionary file.
*/
void loadDictionary(DoublyLinkedBag<char*>& dictionary, const char* filename) {
std::ifstream file(filename);
if (!file) {
std::cerr << "Error: Unable to open dictionary file." << std::endl;
return;
}
char word[100];
while (file >> word) {
toLowerCase(word);
char* wordCopy = new char[strlen(word) + 1];
strcpy(wordCopy, word);
dictionary.add(wordCopy);
std::cout << "Added to dictionary: " << wordCopy << std::endl;
}
file.close();
}
/**
* @brief Checks the spelling of words in an input file against a dictionary.
*
* @param dictionary The DoublyLinkedBag containing the dictionary words.
* @param filename The name of the input file.
* @return A SimpleVector containing the misspelled words.
*/
SimpleVector<char*> checkSpelling(DoublyLinkedBag<char*>& dictionary, const char* filename) {
std::ifstream file(filename);
if (!file) {
std::cerr << "Error: Unable to open input file." << std::endl;
return SimpleVector<char*>();
}
SimpleVector<char*> misspelledWords;
char word[100];
while (file >> word) {
toLowerCase(word);
if (!dictionary.contains(word)) {
char* wordCopy = new char[strlen(word) + 1];
strcpy(wordCopy, word);
misspelledWords.push_back(wordCopy);
std::cout << "Misspelled word: " << wordCopy << std::endl;
}
}
file.close();
return misspelledWords;
}
/**
* @brief Prints the misspelled words.
*
* @param words The SimpleVector containing the misspelled words.
*/
void printMisspelledWords(const SimpleVector<char*>& words) {
if (words.size() == 0) {
std::cout << "No misspelled words found." << std::endl;
} else {
std::cout << "Misspelled words:" << std::endl;
for (int i = 0; i < words.size(); i++) {
std::cout << words[i] << std::endl;
}
}
}
/**
* @brief Frees the memory allocated for the dictionary entries.
*
* @param dictionary The DoublyLinkedBag containing the dictionary entries.
*/
void freeMemory(DoublyLinkedBag<char*>& dictionary) {
SimpleVector<char*> dictionaryContents = dictionary.toVector();
for (int i = 0; i < dictionaryContents.size(); i++) {
std::cout << "Deleting dictionary word: " << dictionaryContents[i] << std::endl;
delete[] dictionaryContents[i];
}
}
/**
* @brief Main function to run the spell checker.
*
* @return int Program exit status.
*/
int main() {
DoublyLinkedBag<char*> dictionary;
const char* dictionaryFile = "dictionary.txt"; // Replace with your dictionary file
const char* inputFile = "input.txt"; // Replace with your input file
loadDictionary(dictionary, dictionaryFile);
SimpleVector<char*> misspelledWords = checkSpelling(dictionary, inputFile);
printMisspelledWords(misspelledWords);
// Free dynamically allocated memory for misspelled words
for (int i = 0; i < misspelledWords.size(); i++) {
std::cout << "Deleting misspelled word: " << misspelledWords[i] << std::endl;
delete[] misspelledWords[i];
}
// Free the dictionary entries
freeMemory(dictionary);
return 0;
}
Node.cpp
#include "Node.h"
#include <iostream>
template<class ItemType>
Node<ItemType>::Node() : next(nullptr), prev(nullptr) {}
template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem) : item(anItem), next(nullptr), prev(nullptr) {}
template<class ItemType>
Node<ItemType>::Node(const ItemType& anItem, Node<ItemType>* nextNodePtr, Node<ItemType>* prevNodePtr)
: item(anItem), next(nextNodePtr), prev(prevNodePtr) {}
template<class ItemType>
void Node<ItemType>::setItem(const ItemType& anItem) {
item = anItem;
}
template<class ItemType>
void Node<ItemType>::setNext(Node<ItemType>* nextNodePtr) {
next = nextNodePtr;
}
template<class ItemType>
void Node<ItemType>::setPrev(Node<ItemType>* prevNodePtr) {
prev = prevNodePtr;
}
template<class ItemType>
ItemType Node<ItemType>::getItem() const {
return item;
}
template<class ItemType>
Node<ItemType>* Node<ItemType>::getNext() const {
return next;
}
template<class ItemType>
Node<ItemType>* Node<ItemType>::getPrev() const {
return prev;
}
template<class ItemType>
Node<ItemType>::~Node() {
// No need to delete item as it is not a pointer.
std::cout << "Node with item " << item << " destroyed." << std::endl;
}
**Node.h**
#ifndef NODE_H
#define NODE_H
template<class ItemType>
class Node {
private:
ItemType item;
Node<ItemType>* next;
Node<ItemType>* prev;
public:
Node();
Node(const ItemType& anItem);
Node(const ItemType& anItem, Node<ItemType>* nextNodePtr, Node<ItemType>* prevNodePtr);
void setItem(const ItemType& anItem);
void setNext(Node<ItemType>* nextNodePtr);
void setPrev(Node<ItemType>* prevNodePtr);
ItemType getItem() const;
Node<ItemType>* getNext() const;
Node<ItemType>* getPrev() const;
~Node();
};
#include "Node.cpp"
#endif // NODE_H
SimpleVector.cpp
#include "SimpleVector.h"
#include <iostream>
template<class ItemType>
SimpleVector<ItemType>::SimpleVector() : items(new ItemType[10]), capacity(10), itemCount(0) {}
template<class ItemType>
SimpleVector<ItemType>::~SimpleVector() {
delete[] items;
std::cout << "SimpleVector destroyed." << std::endl;
}
template<class ItemType>
void SimpleVector<ItemType>::resize(int newCapacity) {
ItemType* newItems = new ItemType[newCapacity];
for (int i = 0; i < itemCount; i++) {
newItems[i] = items[i];
}
delete[] items;
items = newItems;
capacity = newCapacity;
}
template<class ItemType>
void SimpleVector<ItemType>::push_back(const ItemType& item) {
if (itemCount == capacity) {
resize(2 * capacity);
}
items[itemCount] = item;
itemCount++;
}
template<class ItemType>
int SimpleVector<ItemType>::size() const {
return itemCount;
}
template<class ItemType>
ItemType& SimpleVector<ItemType>::operator[](int index) const {
return items[index];
}
**SimpleVector.h**
#ifndef SIMPLE_VECTOR_H
#define SIMPLE_VECTOR_H
template<class ItemType>
class SimpleVector {
private:
ItemType* items;
int capacity;
int itemCount;
void resize(int newCapacity);
public:
SimpleVector();
~SimpleVector();
void push_back(const ItemType& item);
int size() const;
ItemType& operator[](int index) const;
};
#include "SimpleVector.cpp"
#endif // SIMPLE_VECTOR_H
Dictionary.txt
apple
banana
orange
grape
watermellon
pineapple
input.txt
Apple
banana
Orange
grape
Watermelon
pineapple
I am using github codespaces. any advice would be helpful
than you