System.AccessViolationException Attempted to read or write protected memory - c++

Hi im working on a program that uses an array of linked lists but im having trouble running it. I keep getting this error and I cannot find a way to fix it. Im only going to include parts of the code that way everything isnt too cluttered. The error message is saying that lines 112 in NodeADT.h, line 141 in MultiListADT.h and line 21 in main.cpp are the ones throwing the error. Ill highlight those lines to make it easier.
Main.cpp
#include <iostream>
#include "MultiListADT.h"
#include <fstream>
#include <string>
using namespace std;
void main(void)
{
MultiListADT<string,100> myList;
string item;
ifstream data;
string input;
int x=0;
data.open("input.txt");
while (!data.eof())
{
getline(data,input);
myList.AddToFront(input); //This is line 21
}
cout << myList << endl;
system("pause");
}
MultiListADT.h
#include <iostream>
#include <fstream>
#include "NodeADT.h"
#include <string>
using namespace std;
template <class TYPE,int threads>
class MultiListADT
{
public:
/** Constructor **/
MultiListADT();
/** Destructor **/
~MultiListADT();
/** Declare accessors (observers) **/
void ResetListForward(int=0);
void ResetListBackward(int=0);
bool IsEmpty(int=0);
int LengthIs(int=0);
bool Search(string, bool=true,int=0);
void GetNextItem(TYPE &,int i=0);
void GetPreviousItem(TYPE &,int=0);
int GetInfo(int=0);
friend ostream& operator << (ostream&, MultiListADT<TYPE, 100>&);
/** Declare mutators (transformers) **/
void MakeEmpty();
void AddToFront(TYPE);
void AddToRear(TYPE);
void InsertInOrder(TYPE);
void Delete(TYPE);
void Sort();
private:
NodeADT<TYPE,threads>* head[threads];
NodeADT<TYPE,threads>* tail[threads];
int length;
string indices[threads];
NodeADT<TYPE,threads>* currentNode[threads];
};
template <class TYPE,int threads>
MultiListADT<TYPE,threads>::MultiListADT()
{
head[threads] = new NodeADT<string,threads>();
tail[threads] = new NodeADT<string,threads>();
head[threads]->setNext(tail[threads]);
tail[threads]->setPrevious(head[threads]);
length = 0;
}
template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::AddToFront(TYPE item)
{
head[0]->AddToFront(item); //This is line 141
length++;
}
NoteADT.h
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int null = 0;
template<class TYPE, int threads>
class MultiListADT;
template <class TYPE, int threads>
class NodeADT
{
public:
NodeADT();
NodeADT(TYPE);
~NodeADT();
TYPE getInfo();
NodeADT<TYPE, threads>* getPrevious(int=0);
NodeADT<TYPE, threads>* getNext(int=0);
void setNext(NodeADT<TYPE, threads>*,int=0);
void setPrevious(NodeADT<TYPE, threads>*,int=0);
bool Search(TYPE, bool=true,int=0);
void AddToFront(TYPE item);
void AddToRear(TYPE item);
void InsertInOrder(TYPE);
bool Delete(TYPE);
friend ostream& operator << (ostream&, MultiListADT<TYPE, threads>&);
private:
TYPE info;
NodeADT<TYPE, threads>* prev[threads];
NodeADT<TYPE, threads>* next[threads];
};
template <class TYPE,int threads>
NodeADT<TYPE,threads>::NodeADT()
{
prev[threads] = null;
next[threads] = null;
}
template <class TYPE,int threads>
NodeADT<TYPE,threads>::NodeADT(TYPE item)
{
info = item;
prev = null;
next = null;
}
template <class TYPE,int threads>
void NodeADT<TYPE,threads>::AddToFront(TYPE item)
{
NodeADT<TYPE,threads> *temp = new NodeADT<TYPE,threads>;
temp->info = item;
temp->prev[0] = this;
temp->next[0] = next[0];
next[0]->prev[0] = temp; //This is line 112
next[0] = temp;
}

What do YOU think the error means?
On line 112, where do the values for next, prev and temp come from and what are they set to when it crashes? Knowing the values, why do you think it crashed?
Also in one of your NodeADT constructors you assign null to the last element of the array. Or so it appears.
Question: What happens when you assign a value to the element numbered 100 in an array of 100 elements, when element counting starts at 0?

I think the answer, which Zan Lynx has implied, is that you are using threads as an index into your arrays in the constructor of MultiListADT. In AddToFront you use 0 as the index, but that element in the array has never been initialised.

Related

Identifier "buildTree" is undefined

Have a simple error. Looked at a bunch of posts and checked the causes on my files, but couldn't seem to fix it. The functions being called from my BST.cpp file are throwing the error in the title ("identifier "buildTree" is undefined). The functions in question are 'buildTree' and 'performSearchBST'. The CPP file is included in main and the class templates are declared on all of the functions. Probably a simple error but was hoping someone could help point it out for me. Code listed below. As always thank you in advance for your assistance.
Main File:
//..
#include "BST.cpp"
#include "Node.h"
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
//...
ifstream filename("grocery_upc_database.csv");
BST<UPC> tree = buildTree(filename); //build binary search tree of UPC objects
string code;
cout << "Please enter a UPC code(! to quit): ";
cin >> code;
while (code != "!")
{
long entry = stol(code); //convert user inputted string to type long int
UPC key(entry);
performSearchBST(tree, key);
cout << "\nPlease enter a UPC code(! to quit): ";
cin >> code;
}
return 0;
}
BST.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <fstream>
#include "BST.h"
using namespace std;
template <class T>
BST<T>::BST()
{
root = NULL;
}
template <class T>
BST<T>::BST(long upcdata, string descrip)
{
root->data = upcdata;
root->descrip = descrip;
}
template <class T>
void BST<T>::buildTree(string inFile)
{
string upcholder;
string description;
string line;
ifstream file;
file.open("grocery_upc_database.csv");
while (getline(file, line))
{
stringstream ss(line);
getline(ss, upcholder, ',');
getline(ss, description, '\t');
Node<T> newNode;
newNode->data = stol(upcholder);
newNode->descrip == description;
insert(newNode);
}
}
template <class T>
void BST<T>::insert(Node<T> *newNode)
{
insert2(root, newNode);
}
template <class T>
void insert2(Node<T> *&root, Node<T> *newNode)
{
if (root->data = NULL)
{
root = newNode;
}
else if (newNode->data < root->data)
{
insert2(root->left, newNode);
}
else
{
insert(root->right, newNode);
}
}
template <class T>
long BST<T>::stol(string item)
{
long i = atol(item.c_str());
return i;
}
template <class T>
bool BST<T>::performSearchBST(BST<T> bst, UPC key)
{
return performSearchBST2(bst,key);
}
template <class T>
bool performSearchBST2(BST<T> bst, UPC key)
{
if (bst.root == NULL)
return false;
if (bst.root->data == key)
return true;
else if (root->data < key)
return performSearchBST2(root->right, key);
else
return performSearchBST2(root->left, key);
}
BST.h
#include <iostream>
#include <string>
#include "Node.h"
using namespace std;
template <class T>
class BST
{
Node<T> *root;
public:
BST();
BST(long key, string descrip);
bool find(T item);
bool performSearchBST(BST<T> bst, UPC key);
void buildTree(string inFile);
void insert(Node<T>* newNode);
long stol(string item);
};
You have a simple error here.
First and foremost, your compiler doesn't know what is buildTree(String).
You have a non-static member function whose name is BST<T>::buildTree(String).
Secondly, as said in the comments, you cannot use such a non-static member function without an object of that type, since it operates on a specific object.
You can get by either:
Using it as a member function, thus:
BST<UPC> tree{};
tree.buildTree(filename);
Or, transform the function into a static function that builds a tree, and it should look like:
static BST<T> buildTree(string inFile)
{
\* Create and build the tree inside
return the tree
*/
}
and then you can use it by:
BST<UPC> tree = BST<UPC>::buildTree(filename);
Which is the proper name of the function.
Also, when using templates, you need to declare and define the function within the same .hpp file see this question for more information.

How do I fix my object initialization for a template BST class?

This problem occurs in my main.cpp:
using namespace std;
#include <iostream>
#include "BST.h"
#include "Packet.h"
int main()
{
BST test; // It occurs on this line!
Packet one(1, "testPacket", 1, 1);
system("Pause");
}
The error on that line says:
argument list for class template "BST" is missing
I don't know how to fix it. I just want to initialize the BST. How can I fix this error? I'm not very experienced with templates. Please help. My priority is fixing this glaring problem right now. Can I get help?
For reference purposes:
BST.h:
#ifndef BST_H
#define BST_H
using namespace std;
template <typename T>
class Node {
public:
Node() : rlink(nullptr), llink(nullptr) {}
~Node() {}
private:
T data;
Node *rlink, *llink;
};
template <typename T>
class BST {
public:
BST();
void insert(T data);
private:
Node * root;
};
#endif
BST.cpp
#include "BST.h"
template <typename T>
BST<T>::BST() : root(nullptr) {}
template <typename T>
void BST<T>::insert(T data) {
if (root != nullptr) {
}
else {
cout << "NPTR" << endl;
}
}
Packet.h
#ifndef PACKET_H
#define PACKET_H
#include <string>
using namespace std;
class Packet {
public:
Packet(int partId, string description, double price, int partCount) :
partId(partId), description(description), price(price), partCount(partCount) {}
int getPartId() const { return partId; }
string getDescription() const { return description; }
double getPrice() const { return price; }
int getPartCount() const { return partCount; }
private:
int partId;
string description;
double price;
int partCount;
};
#endif
There are 2 problems.
The first is that Node needs to know what type T is, so you need to tell it when you use Node like this:
template <typename T>
class BST {
public:
BST();
void insert(T data);
private:
Node<T> * root;
};
Secondly, BST needs to know what its own type T is when you try to use it, so you need to do it like this:
BST<int> test; // Or whatever you are searching for in your tree. Doesn't have to be an int
P.S. Just heading this off now, you're probably going to need to implement BST in the header file. Failure to do so might cause linker problems.
P.P.S. I've been reading your comments on the original post, and what you actually probably need this instead:
BST<Packet> test; // Since you are searching for packets.

C++ Linker Error - Defining things twice

To start off, I'm kind of new to instantiation files, headers, and source files.
I'm trying to get my code to compile, but I keep hitting a linker error where it says that I'm defining something twice.
I have 6 Files:
- Instantiation.cpp Lab5.cpp Students.cpp Queue.cpp Students.h Queue.h
Instantiation:
#include "Students.cpp"
#include "Lab5.cpp"
#include "Queue.cpp"
template class Queue<int>;
template class QueueNode<int>;
template class Queue < Students* >;
template class QueueNode < Students* >;
Lab5:
#include "Queue.h"
#include "Students.h"
#include <iostream>
using namespace std;
int main(){
Queue <Students*> studentQueue;
Queue <int> integerQueue;
return 0;
}
Students.cpp:
#include "Students.h"
Students::Students(){
}
void Students::printStudent(){
}
Queue.cpp:
#include "Queue.h"
template <class DataType>
Queue<DataType>::Queue(int i){
i = queueSize;
}
template <class DataType>
Queue<DataType>::~Queue(){
}
template <class DataType>
void Queue<DataType>::enQueue(const DataType){
}
template <class DataType>
DataType Queue<DataType>::deQueue(){
return 0;
}
template <class DataType>
DataType Queue<DataType>::topQueue() const {
return 0;
}
template <class DataType>
bool Queue<DataType>::isEmpty() const {
return true;
}
template <class DataType>
bool Queue<DataType>::isFull() const{
return true;
}
Students.h:
#ifndef STUDENTS_H
#define STUDENTS_H
class Students{
public:
char lastName[20];
char firstName[20];
int ID; // ID
Students(); // constr
void printStudent(); // print info
};
#endif
Queue.h:
#ifndef QUEUE_H
#define QUEUE_H
template <class DataType>
class QueueNode {
public:
DataType data;
QueueNode<DataType> *next;
};
template <class DataType>
class Queue {
private:
QueueNode<DataType> *front;
QueueNode<DataType> *back;
int queueSize; // size of a Queue
int queueCnt; // elem count in a Queue
public:
Queue(int = 10); // class constr. - initialize vars
~Queue(); // class destructor - remove all mem space used by queue elems
void enQueue(const DataType); // add item to back of queue
DataType deQueue(); // remove first item from queue and return its value
DataType topQueue() const; // return the value of the first item in the queue
bool isEmpty() const; // returns true if there are no elems in the queue
bool isFull() const; // returns true if no system mem for a new queue node
};
#endif
Here's the output:
http://i.imgur.com/cAPdtKG.png
Please, help.
I don't really get why it thinks I'm defining anything twice.

How to use a templated client display() function that takes a set as the parameter

I have to write a templated client function called DisplaySet() that gets as an argument a set, and displays the contents of the set. I am confused on how I can output the set, which is part of a class, in a client function.
Here is my code:
"set.h"
template<class ItemType>
class Set
{
public:
Set();
Set(const ItemType &an_item);
int GetCurrentSize() const;
bool IsEmpty() const;
bool Add(const ItemType& new_entry);
bool Remove(const ItemType& an_entry);
void Clear();
bool Contains(const ItemType& an_ntry) const;
vector<ItemType> ToVector() const;
void TestSetImplementation() const;
private:
static const int kDefaultSetSize_ = 6;
ItemType items_[kDefaultSetSize_];
int item_count_;
int max_items_;
int GetIndexOf(const ItemType& target) const;
};
template<class ItemType>
void DisplaySet(const Set<ItemType> &a_set);
"set.cpp"
template<class ItemType>
void DisplaySet(const Set<ItemType> &a_set){
int a_size = a_set.GetCurrentSize(); //gets size of the set
cout <<"Size display "<< a_size << endl;
for (int i = 0; i < a_size; i++) {
cout << a_set[i] << endl; //i know this does not work because a_set is part of a class
}
}
"main.cpp"
#include <iostream>
#include <vector>
#include <string>
#include "Set.h"
using namespace std;
int main()
{
Set<int> b_set;
b_set.Add(setArray[1]);
b_set.Add(setArray[2]);
b_set.Add(setArray[4]);
b_set.Add(setArray[8]);
DisplaySet(b_set);
return 0;
}
I hope someone can explain how to use the function. Let me know if I need to post more of the code
Your Set class does not have an overloaded operator[], so calling a_set[i] is not going to work in your DisplaySet function.
Assuming that your ToVector function returns a vector of the items in the set, the DisplayFuntion can look like this:
#include <iterator>
#include <algorithm>
#include <iostream>
//...
template<class ItemType>
void DisplaySet(const Set<ItemType> &a_set)
{
std::vector<ItemType> v = a_set.ToVector();
std::copy(v.begin(), v.end(), std::ostream_iterator<ItemType>(cout, "\n"));
}
Again, this is assuming that ToVector does as stated.

how to change from a list of strings to a list of pointers to strings

I am trying to get this to return a string, but i am having trouble getting it working. The goal is to have a doubly-linked list that points to strings. I am not allowed to have it contain the string, it must point to it instead. Currently i am having trouble getting my program to use it. For example, it always seems to return what the command was, and its confusing me and hard to explain.
#ifndef DOUBLY_LINKED_LIST_H
#define DOUBLY_LINKED_LIST_H
#include <iostream>
#include <string>
//#include "Playlist.h"
using namespace std;
class DoublyLinkedList
{
public:
DoublyLinkedList();
~DoublyLinkedList();
bool empty();
void append(string& s);
void insertBefore(string& s);
void insertAfter(string& s);
void remove(string& s);
void begin();
void end();
bool next();
bool prev();
bool find(string& s);
const string& getData();
private:
class Node
{
public:
Node (string *data, Node *next, Node *prev)
{m_data = data; m_next = next; m_prev = prev;}
string *m_data;
Node * m_next;
Node * m_prev;
};
Node *m_head;
Node *m_tail;
Node *m_current;
};
#endif // DOUBLYLINKEDLIST_H_INCLUDED
.cpp file>>>>
const string& DoublyLinkedList::getData()
{
string *m_tmp;
m_tmp = m_current->m_data;
cout << m_current->m_data << endl;
//cout << "returning: " << m_current->m_data << endl;
// return m_current->m_data;
return *m_tmp;
}
void DoublyLinkedList::append(string &s)
{
if (!m_head)
{
m_head = new Node(&s, NULL, NULL);
m_tail = m_head;
m_current = m_head;
}
else
{
m_tail->m_next = new Node (&s, NULL, m_tail);
m_tail = m_tail->m_next;
m_current = m_tail;
}
}
Consider the following example:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void store_value(vector<string*>& vec, string& str)
{
vec.push_back(&str);
}
void create_and_store_value(vector<string*>& vec)
{
string str("This string is temporary");
store_value(vec, str);
}
int main(int argc, char** argv)
{
vector<string*> pointers;
create_and_store_value(pointers);
cout << *pointers.back() << endl;
string myPersistingString("Yay");
store_value(pointers, myPersistingString);
cout << *pointers.back() << endl;
return 0;
}
This example contains two function, a function store_value which behaves similar to your append function (except, for the purposes of this example working on a std::vector) and a second function showing the possible danger of taking the address of a reference (this is one of the possible hazards that I believe Manu343726 and Mats Petersson are preluding too).
The reason this is dangerous is because the string declared inside create_and_store_value does not persist after the completion of the function. This means that we are left with a pointer to memory which is probably not what we expect. On the other hand, creating a string inside the main function is fine, since the string there persists until the end of the program.
For us to help you further, I would suggest editing your question to give us an example of how you are calling your function. I would suggest pasting a minimal striped down version of your code including an example of how you are calling append, something like:
#include <blah>
class DoubleLinkedList
{
DoubleLinkedList(void)
{
// Include these inline to make copying and pasting simpler.
}
~DoubleLinkedList(void)
{
...
}
append(...) { ... }
getData(...) { ... }
};
int main(int argc, char** argv)
{
DoubleLinkedList dll;
// Show us how you are using this list
return 0;
}
In the above, replace the comments and dots with the relevant code.