What is Causing this STATUS_ACCESS_VIOLATION? - c++

I suck at c++ so i suspect it's a dumb mistake I have made. After a bit of research I see that that STATUS_ACCESS_VIOLATION happens when the program tries to access invalid memory blocks. That said I'm not seeing what is causing that to happen in the code below.
int main() {
cout << "!!!Hello World!!!" << endl;
Node* testNode = new Node("jhon","doe", 1, 80);
BraidedLinkedList* testList = new BraidedLinkedList();
testList->AddNode(testNode);
return 0;}
BraidedLinkedList.cpp
void BraidedLinkedList::AddNode(Node *newNode) {
if (this->start == NULL) {
this->start = newNode;
cout<<newNode->getInfo();
//the following line does not work either
//cout<<this->start->getInfo()<<endl;
}
Node.cpp
const string& Node::getInfo() {
string returnString = "";
returnString += this->getFristName() + " ";
returnString += this->getLastName() + " ";
returnString += this->getId() + " ";
returnString += this->getGrade() + " ";
}

Your 'Node::getInfo' method is returning a const reference to a temporary string object. At the point at which it attempts to print the string it's highly likely it could crash. I'm assuming you simply left out the return. In this scenario the return type should simply be 'string'.

Related

How to fix my function popFront for my list?

My program is a list of cities, it's good but when I call to popFront(), I don't know why but it doesn't work, then I call any function and the program is over.
City* popFront(Nodo*& header, Nodo*& trailer) {
City* libras;
if (inicio) {
strcpy(libras->Name,inicio->dato.Name );
libras->Num = header->dato.Num;
Nodo* aux = header;
header= header->next;
header->previous= NULL;
delete aux;
if (!header) trailer = NULL;
}
return libras;
}
void read(Nodo*& head) {
Nodo* aux = head;
int pos = 1;
while (pos <= node_count) {
cout << "pos" << pos << endl;
cout << "Name> " << aux->dato.Name << endl;
cout << "NUm> " << aux->dato.Num << endl;
aux = aux->next;
pos++;
}
if (node_count == 0)cout << "Empty list" << endl;
}
Well, I'm not sure this is the only problem, but this right here is wrong:
City* libras;
You need to allocate it before you use it, like this:
City* libras = new City;
Otherwise, something like strcpy(libras->Name,inicio->dato.Name ); will fall and crash hard. That's because it's UB (Undefined Behavior) to access a pointer to memory that is unallocated.
Of course, you will need to delete it when you're done with it, but you seem to know and understand that already based on your other code:
delete libras; // Or wherever the returned pointer gets stored

Has no member named, BST

I'm creating a binary tree and trying to print the names of a student object which im passing in. When I try to print the tree, I get an error:
tree.h:181:46: error: ‘class samuel::Student’ has no member named ‘printInOrder’
str += Node->get_data().printInOrder() + "\n";
This is the function I'm calling in main using
BSTree<Student>* student_tree = new BSTree<Student>;
Student student = Student("Adam");
student_tree->insert(student);
student_tree->printInOrder();
string printInOrder(){return inOrder(root, 0);}
private:
string inOrder(BTNode<value_type>* Node, size_t level)
{
string str ="";
if(Node != NULL)
{
str += inOrder(Node->get_right(), level++);
for(int i = 1; i <= level; ++i)
{
str = str + "| ";
}
str += Node->get_data().printInOrder() + "\n";
str += inOrder(Node->get_left(), level++);
}
return str;
}
I'm not sure why when I try to access printInOrder it goes through Student. This is my student class
typedef Student value_type;
Student::Student()
{
}
Student::Student(std::string init_name, float init_grade)
{
name = init_name;
std::string studentName[50]={"Adam", "Cameron", "Jackson", "KiSoon", "Nicholas", "Adrian", "Chris", "Jacob", "Lance", "Ryan",
"Alexander", "Damian", "James", "Liam", "Sang", "Andrew", "David", "Jared", "Madison", "Shane", "Ashley", "Dillon",
"Jodi", "Magdalena", "Simon", "Benjamin", "Dylan", "Jonathan", "Marcus", "Thomas", "Bradley", "Ethan" "Joshua", "Mark",
"Timothy", "Brobie", "Frederik", "Julius", "Melanie", "Trent", "Callan", "Hong", "Kelly", "Min", "Troy", "Callum", "Hugh", "Kenias", "Mitchell", "Zaanif"};
for (int i = 0; i <50; i++)
{
int j = (rand() % (i-1));
string temp = studentName[j];
studentName[j] = studentName[i];
studentName[i] = temp;
}
}
Student::~Student()
{
}
void Student::set_name(string new_name)
{
name = new_name;
}
const string Student::get_name() const
{
return name;
}
void Student::set_grade(float new_grade)
{
grade = new_grade;
}
float Student::get_grade()
{
return grade;
}
An alternative method I tried was using
string infix(BTNode<value_type>* Node)
{
if (Node == NULL)
{
return "";
}else{
return (infix(Node->get_left()) + Node->get_data()) +
infix(Node->get_right());
}
}
friend ostream& operator << (ostream& out, const BSTree<value_type>& tree)
{
out << tree.infix(tree.root) << endl;
return out;
}
and then calling cout << student_tree << endl however this printed a memory address, would anyone also be able to clarify why that happens as well, thanks
Edit: Changed how I was inserting a student. Changed cout << student_tree << endlto cout << *student_tree << endlwhich gave the error
tree.h:70:9: error: passing ‘const samuel::BSTree’ as ‘this’ argument discards qualifiers [-fpermissive]
out << tree.infix(tree.root) << endl;
tree.h:181:46: error: ‘class samuel::Student’ has no member named ‘printInOrder’
Node->get_data() returns object of samuel::Student type because of this compiler searches for printInOrder() in samuel::Student type. It's not there according to the code above. To fix the issue implement the method:
std::string Student::printInOrder()
{
// Return the data to be printed
}
student_tree->insert(* new Student());
Looks suspicious. Tree contains Student objects by value. You create an Student object on the heap, dereference pointer and copies value into the Tree. Pointer lost after that. This will cause memory leak problem.
cout << student_tree << endl however this printed a memory address
Because it's declared as BSTree<Student>* student_tree. It's a pointer to the tree, so the output is correct, you print the address. To print the tree value you need to dereference the pointer: cout << *student_tree << endl.
continuation to other answer...
and then calling cout << student_tree << endl however this printed a
memory address, would anyone also be able to clarify why that happens
as well, thanks
BSTree<Student>* student_tree = new BSTree<Student>;
student_tree is a pointer to BSTree<Student> it means it holds the memory location(a memory address) of BSTree object which is an unnamed object in this case.
you must dereference it to get the value inside the address by doing *student_tree
std::cout << *student_tree; // actual value, and will call operator<<

Core Segmentation Fault With Vector

The following pertains to homework. Restraunt pet project type thing, task is to update it to use vectors. The issue I'm having is this:
This winds up causing a core segmentation fault, yet is able to retrieve all the information appropriately when I use valgrind.
void Table::partyCheckout(void)
{
if(status == SERVED)
{
cout << " ---------------- " << endl;
cout <<"Table: " << tableId << "\nParty Size: " << numPeople << "\nWaiter: " << waiter->getName() << "\nSummary: " <<endl;
order->requestSummary();
cout << "Total: " << endl;
order->requestTotal();
cout << " ---------------- " << endl;
status = IDLE;
}
else
{
cout << "Error: " << tableId << " ";
if(numPeople == 0)
{
cout << "No one is at this table." << endl;
}
else
{
cout << "This party hasn't been served." << endl;
}
}
}
Setup: I'm storing the waiters and the orders in vectors.At runtime: when it does the waiter->getName() it complains that it's an invalid read, and that the memory location has been free'd by vector via a deallocater. My logic on the matter: It looks ahead and sees that the vector itself is not accessed again and so deallocates it. Since I do no more writing after this point, the memory location remains intact. When it tries to read the location it sees it has been free'd, hence invalid read but it still gets the appropriate data. So my question then, I suppose is two fold:Does this logic sound right? What should I do to fix it?
#ifndef HW3_H
#define HW3_H
#include <vector>
#include "Table.h"
#include "Waiter.h"
class hw3
{
private:
vector<Table> tables;
vector<Waiter> waiters;
vector<Order> orders;
public:
void begin();
};
#endif
.cpp file, most of the allocation:
ifstream configFile("config.txt"); //This guy is for initializing things
string line;
Menu theMenu;
getline(configFile, line);
stringstream intMaker;
int t1;
int t2;
string temp;
string temp2;
string temp3;
while (true)
{
getline(configFile, line);
Tokenizer str(line, " \n");
if(line =="")
{
break;
}
else
{
temp = str.next();
temp2 = str.next();
intMaker << temp;
intMaker >> t1;
intMaker.str("");
intMaker.clear();
intMaker << temp2;
intMaker >> t2;
intMaker.str("");
intMaker.clear();
tables.push_back(*(new Table(t1,t2)));
}
}
getline(configFile, line);
while (true)
{
getline(configFile, line);
Tokenizer name(line, " ");
string tabl = "";
//Siphon off the name and the tables.
temp = name.next();
tabl = name.next();
Tokenizer strink(tabl, ",\n");
int numTables = (int) tables.size();
Table * tabs[numTables];
t1 = 0;
int keepinTabs = 0;
while(true)
{
string temp2 = strink.next();
if (temp2 == "")
{
break;
}
else
{
intMaker << temp2;
intMaker >> t1;
intMaker.str("");
intMaker.clear();
for(int i = 0; i < numTables; i++)
{
if(tables.at(i).getTableId() == t1)
{
tabs[keepinTabs] = &tables.at(i);
}
}
keepinTabs++;
}
}
waiters.push_back(*(new Waiter(temp, tabl, *tabs))); //Waiter(name, list of tables, and an array of table numbers.
for(int j = 0; j < keepinTabs; j++)
{
for(int i = 0; i < tables.size(); i++)
{
if(tabs[j]->getTableId() == tables[i].getTableId())
{
tables.at(i).assignWaiter(&(waiters.back()));
}
}
}
if(line == "")
{
break;
}
}
Multiple issues I can see:
tables.push_back(*(new Table(t1,t2)));
This code dynamically allocates an object of type Table, then pushes a copy of this object into tables, and then forgets the address of the dynamically allocated object - you're leaking memory.
waiters.push_back(*(new Waiter(temp, tabl, *tabs)));
As above, with Waiter this time.
tabs[keepinTabs] = &tables.at(i);
This takes the address of an object inside the vector. While legal, it's extremely fragile. std::vector can move its contents around in memory when it resizes (e.g. when you push into it).
This (or similar code elsewhere) might be the cause of your segfault. Seeing as you're allocating the objects dynamically, maybe you should declare your vectors to hold just pointers:
vector<Table*> tables;
vector<Waiter*> waiters;
vector<Order*> orders;
You would then do e.g. tables.push_back(new Table(t1, t2));. Of course, you have to make sure to delete the dynamically allocated objects when you remove them from the vectors. An alternative would be to use smart pointers, e.g.:
vector<std::shared_ptr<Table> > tables;
vector<std::shared_ptr<Waiter> > waiters;
vector<std::shared_ptr<Order> > orders;

VS'08 C++ Access Violcation When Initialising Pointer Previously had no issues

I'm writing a code to index the skills available to a user in a game, constructed as a linked list. I've throughly tested the function that populates the list and it seems to be working correctly (so the head pointer for the list shouldn't be null). When I attempt to traverse the list to set values in the skill, before any of the code which writes to memory within the list gets to execute the program is crashing when I initialise the temp pointer within the search function of the list to the head pointer.
What makes this additionally weird to me is that it worked fine (and I had tested this fairly thuroughly) until I added in a list to store a list of available items, and may just be missing an odd interaction between the two when I populate them.
The specific error is that the pointer is supposedly accessing memory index 0x000000c to write to, but I don't see how the code at that point is dealing with a null pointer at all (since after 10 runs of the program the OS shouldn't be allocating that block of memory to the temp pointer every time and nothing else should be null.
I'm probably just ramblind at this point so here's the code:
The function that causes the error according to the debugger:
void Mechanics::setSkillValue(int index, int value)
{
Skill *temp = FirstSkill; // << The error is happening on this line //
while((temp != NULL)&&(temp->index != index))
{
temp = temp->next;
}
if (temp == NULL)
{
cout << "%";
}
else temp->setValue(value);
// cout << temp->returnValue(); //This was a test check, not needed for anything
}
The Function that's supposed to populate the skill and item lists.
void Mechanics::Populate()
{
ifstream skillstream("Skills.txt");
if(skillstream.is_open())
{
while(skillstream.good())
{
Skill *newskill;
int indexval;
string skillindex;
string skillname;
string skilldescription;
cout << "TP4" << endl; //TEST POINT
getline(skillstream, skillindex);
cout << skillindex;
getline(skillstream, skillname);
cout << skillname;
getline(skillstream, skilldescription);
cout << skilldescription; cout << endl;
indexval = atoi(skillindex.c_str());
newskill = new Skill(skillname, skilldescription,indexval);
//cout << "TP5" << endl; //TEST POINT
if(newskill == NULL) cout << "NULL!!!";
addSkill(newskill);
}
}
ifstream itemstream("Items.txt");
if(itemstream.is_open())
{
while(itemstream.good())
{
Item *newitem;
int indexval;
string skillindex;
string skillname;
string skilldescription;
string abilitydescription;
string valueSTR;
string typeSTR;
int value;
int type;
int numeric[5];
// cout << "TP4" << endl; //TEST POINT
getline(itemstream, skillindex);
// cout << skillindex;
getline(itemstream, skillname);
// cout << skillname;
getline(itemstream, skilldescription);
// cout << skilldescription;
getline(itemstream, abilitydescription);
getline(itemstream, valueSTR);
value = atoi(valueSTR.c_str());
getline(itemstream,typeSTR);
type = atoi(typeSTR.c_str());
for (int i=0; i < 5; i++)
{
string numericSTR;
getline(itemstream,numericSTR);
numeric[i]=atoi(numericSTR.c_str());
}
indexval = atoi(skillindex.c_str());
newitem = new Item(indexval, skilldescription, skillname, abilitydescription, value, type, numeric);
//cout << "TP5" << endl; //TEST POINT
// if(newskill == NULL) cout << "NULL!!!";
addItem(newitem);
}
}
The function that's supposed to actually add a skill to the skill list:
void Mechanics::addSkill(Skill *nskill)
{
Skill *temp = FirstSkill;
if(FirstSkill == NULL)
{
FirstSkill = nskill;
//cout << "TP1" << endl; //TEST POINT
//FirstSkill->printname();
}
else
{
while((temp->next != NULL))
{
temp = temp-> next;
//cout << "TP2" << endl; //TEST POINT
//temp->printname(); cout << endl;
}
if (FirstSkill != NULL)
{
temp->next = nskill;
nskill->next = NULL;
}
}
}
The code that I have is somewhat extensive so I'm only going to include the blocks which are potentially interacting with the function that's throwing up the error.
Thanks in advance for reading through this, and any assistance you're able to offfer, I've been banging my head against this for about 6 hours now and I've lost the perspective to actually track this one down.

Runtime error printing string, even though it works fine in a function

working on a simple C++ pointer-based stack program. I am attempting to print a string which is part of the NameItem class which the PointerStack class uses as its item type (see code). Whenever I try to print the string in the main() function of my program, the console prints gibberish and beeps repeatedly. However, when I call the PrintPointerStack function, there are no errors and everything prints as expected.
I'd tried changing the classes, rearranging the code, and while I can pinpoint which line generates the error I can't figure out why. I'm completely lost here, never seen anything like this before, so I'm sorry if the answer is simple and found in a google search but I've been going for hours and just don't know what to search anymore.
Code is below:
#include <iostream>
#include <string>
#include <stack>
#include <cstddef>
#include <new>
using namespace std;
#include "NameItem.cpp"
#include "Stack.cpp"
#include "PointerStack.cpp"
void PrintPointerStack(PointerStack printer){
NameItem temp;
while(!printer.IsEmpty()){
temp = printer.Top();
printer.Pop();
temp.Print();
}
cout << endl;
}
int main(){
string initNames[] = {"Michael","Charlie","Susan","Alexa",
"Jason","Candice","Beatrice","Lois",
"Peter","Matthew"};
int initNamesLen = 10;
PointerStack PStacker, tempPStacker;
NameItem filler;
for(int i = 0; i < initNamesLen; i++){
filler.Init(initNames[i]);
PStacker.Push(filler);
}
cout << endl << "---------- Pointer-based Stack ----------" << endl << endl;
PrintPointerStack(PStacker);
cout << "Top: ";
(PStacker.Top()).Print(); //This is where the program errors. I've tried creating a
//temp variable like in the function above, and I've
//tried accessing the string directly and printing it
//from main() using cout, which produce the same results.
//So the error is caused specifically by the cout <<
//string statement, when I try to use that statement
//within the bounds of the main function.
cout << endl;
PrintPointerStack(PStacker);
cout << endl << "Popped: ";
(PStacker.Top()).Print();
PStacker.Pop();
(PStacker.Top()).Print();
PStacker.Pop();
cout << endl;
PrintPointerStack(PStacker);
cout << endl << "Pushed: Sammy Valerie" << endl;
filler.Init("Sammy");
PStacker.Push(filler);
filler.Init("Valerie");
PStacker.Push(filler);
PrintPointerStack(PStacker);
try{
PStacker.Push(filler);
}
catch(FullStack){
cout << endl << "Stack is full, name not pushed" << endl;
}
cout << endl << "Popped: ";
while(!PStacker.IsEmpty()){
filler = PStacker.Top();
PStacker.Pop();
filler.Print();
}
try{
PStacker.Pop();
}
catch(EmptyStack){
cout << endl << "Stack is empty, name not popped" << endl;
}
return 0;
}
The PointerStack class
#include "PointerStack.h"
PointerStack::PointerStack(){
top = NULL;
}
/*PointerStack::~PointerStack(){
Node* temp;
while(top != NULL){
temp = top;
top = top->next;
delete temp;
}
}*/
void PointerStack::Push(NameItem item){
if(IsFull())
throw FullStack();
else{
Node* location;
location = new Node;
location->data = item;
location->next = top;
top = location;
}
}
void PointerStack::Pop(){
if(IsEmpty())
throw EmptyStack();
else{
Node* temp;
temp = top;
top = top->next;
delete temp;
}
}
NameItem PointerStack::Top(){
if(IsEmpty())
throw EmptyStack();
else{
return top->data;
}
}
bool PointerStack::IsEmpty() const{
return (top == NULL);
}
bool PointerStack::IsFull() const{
Node* location;
try{
location = new Node;
delete location;
return false;
}
catch(std::bad_alloc& exception){
return true;
}
}
And the NameItem class
#include <fstream>
#include "NameItem.h"
NameItem::NameItem()
{
name = " ";
}
RelationType NameItem::ComparedTo(NameItem otherItem) const
{
if (name < otherItem.name)
return LESS;
else if (name > otherItem.name)
return GREATER;
else
return EQUAL;
}
void NameItem::Init(string value)
{
name = value;
}
void NameItem::Print() const
{
cout << name << " ";
}
Final note, the main program has more code for testing the Stack class included in the program. I removed the code since it is not related to the error, and the program still crashes, but it crashes immediately with a windows error box rather than with console gibberish/beeps. Not sure if that is relevant or not...
The problem is twofold.
First, you are emptying the PStacker object in PrintPointerStack(), then trying to access the top element of that empty stack. This should throw an EmptyStack. The fact that this is not happening, indicates another problem as well (see below).
Second, the fact that giberish is printed (sometimes) indicates that you are trying to access data through invalid objects/pointers. Indeed, because you are passing the parameter of PrintPointerStack() via pass-by-value, the default copy-constructor is invoked that blindly copies the value of the top pointer. Then you proceed to delete objects, but the top pointer in the original PStacker is not changed, thus now is invalid. Hence your problem.
To fix, you either need to pass the parameter to PrintPointerStack() by pointer/reference or provide a better suiting copy-constructor that does a deep copy (instead of the shallow copy provided by the default copy-constructor).