alright, this is a bit complicated for me to understand but ill explain it simply. Right now I in the middle of making a parser. part of making that parser is to make a parse tree. the first code snip below is the class for the parse tree where the label is like the node itself. nonTerms is just an enum of non-terminal names. the children here can either be terminals(tokens in the tk[]) or another non-terminal(nodeTK in children[]).
node.h
enum nonTerms{
PARSER,
PROG,
BLOCK,
VARS,
STATS,
STAT,
MSTAT,
IN,
OUT,
IF_,
LOOP,
ASSIGN,
GOTO_,
LABEL,
R0_,
EXPR,
N_,
A_,
M_,
R_,
none = -1
};
class nodeTK{
public:
nonTerms label;
std::vector<int> printOrder;
int tkIndex = 0;
Token* tk[5] = {nullptr, nullptr, nullptr, nullptr, nullptr};
int ntIndex = 0;
nodeTK* children[4] = {nullptr, nullptr, nullptr, nullptr};
nodeTK(); // creates a null node
nodeTK(nonTerms); //creates a node with specified nonterminal name
void pushTk(Token); //adds a token to the tk[]
void pushChild(nodeTK*); // adds a child to the children[]
nonTerms getLabel(); // returns the label of the current node
std::string printLabel(); // prints the string equivalent of the label
Token* getTk(int); // retrieves a specific tk in current node
nodeTK* getChild(int); // retrieves a child from current node
};
node.cpp
std::string myLabels[21] = {
"PARSER",
"PROG",
"BLOCK",
"VARS",
"STATS",
"STAT",
"MSTAT",
"IN",
"OUT",
"IF",
"LOOP",
"ASSIGN",
"GOTO",
"LABEL",
"R0",
"EXPR",
"N",
"A",
"M",
"R",
"none"
};
nodeTK::nodeTK(){
label = none;
}
nodeTK::nodeTK(nonTerms non_terminal){
std::cout << non_terminal << std::endl;
label = non_terminal;
}
void nodeTK::pushTk(Token token){
if(tkIndex < 5){
printOrder.push_back(1);
tk[tkIndex] = &token;
tkIndex++;
}else{
std::cout << "your pushing too many tokens in this node with tk " << token.getInstance() << std::endl;
}
}
void nodeTK::pushChild(nodeTK* nodeChild){
if(ntIndex < 4){
printOrder.push_back(0);
children[ntIndex] = nodeChild;
std::cout << children[ntIndex]->getLabel() << std::endl;
ntIndex++;
}
else{
std::cout << "your pushing too many non-terminals in this node" << std::endl;
}
}
nonTerms nodeTK::getLabel(){
std::cout << "hello" << std::endl;
return label;
}
std::string nodeTK::printLabel(){
std::string str = myLabels[label];
return str;
}
Token* nodeTK::getTk(int index){
return tk[index];
}
nodeTK* nodeTK::getChild(int index){
return children[index];
}
void nodeTK::preOrder(){
std::cout << printLabel() << std::endl;
int tkIndex = 0;
int childIndex = 0;
for(int i = 0; i < printOrder.size(); i++){
if(printOrder.at(i) == 1){
std::cout << getTk(tkIndex)->getInstance() << std::endl;
tkIndex++;
}else if(printOrder.at(i) == 0){
nodeTK * temp;
std::cout << getChild(childIndex)->getLabel() << std::endl;
childIndex++;
}else{
std::cout << "something went wrong" << std::endl;
}
}
}
this is where the issue is. As you can see this function receives a node pointer which I then assign to one of the still null children in the children[]. all I want to do is print the label of the child node after it has received the pointer to check that it was retrieved correctly. getLabel() should return an enumerated value and the cout should just output some number. Every time I attempt to run getLabel() in the program ends with a segmentation fault at exactly that function call. I know it partly runs because I put some dummy cout statements to see if the function runs and the couts to appear in the terminal. I'm not sure exactly what I'm doing wrong though. Sorry if my question is not super clear, I feel like I'm still a noob to pointers.
void nodeTK::pushChild(nodeTK* nodeChild){
if(ntIndex < 4){
printOrder.push_back(0);
children[ntIndex] = nodeChild;
std::cout << children[ntIndex]->getLabel() << std::endl;
ntIndex++;
}
else{
std::cout << "your pushing too many non-terminals in this node" << std::endl;
}
}
here's the getLabel function:
nonTerms nodeTK::getLabel(){
std::cout << "hello" << std::endl;
return label;
}
here's the output of the code.
hello
Segmentation fault
thank you again
Related
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
I need some help with my code. The function findNode lies within a header file, and is called in the main. As you can see, findNode calls itself until it finds the correct data value in each of the nodes. The type of tree implemented is a General Tree.
My problem is that the function does find the TreeNode it needs to find, but it returns it incorrectly. The data value of p in main is empty
TreeNode<Type>* findNode(Type &_data, TreeNode<Type>* _ptr)
{
if(_ptr->data == _data)
{
cout << "ptr->data: " << _ptr->showData() << endl;
return _ptr;
}
if(_ptr->children != NULL)
{
findNode(_data, _ptr->children->getHead());
}
if(_ptr->getNext() != NULL)
{
findNode(_data, _ptr->getNext());
}
}
In MAIN:
.
.
case 3:
{
string data;
cout << "****************" << endl;
cout << "***findNode()***" << endl;
cout << "Data to find: " << endl;
cin >> data;
TreeNode<string>* p = Tree->findNode(data, Tree->getRoot());
cout << "p->data = " << p->showData() << endl;
break;
}
add "return" in front of findNode(..) to fix the issue.
if(_ptr->children != NULL)
{
return findNode(_data, _ptr->children->getHead());
}
if(_ptr->getNext() != NULL)
{
return findNode(_data, _ptr->getNext());
}
unless the data matches in the first time, it is not returned. it is merely called and the result is let go.
In your original code, Say the data is matched in 4 th level of function call:
findNode1->findNode2->findNode3->findNode4
then this happens:
findNode4 returns ptr to findNode3, which does not return anything as it just called the function without expecting any value back.
At your level of skill it is very good to practice "uniform coding" :
retval = _ptr;
}
else if(_ptr->children != NULL)
{
retval = findNode(_data, _ptr->children->getHead());
}
else if(_ptr->getNext() != NULL)
{
retval = findNode(_data, _ptr->getNext());
}
return retval; // return from single point.
it is merely a style not technically better, but imho gradual learning is better.
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.
Let's see I want to do this, i want to get the parent of a tree, then sum the nodes and putthe result in the parent, this is multithreaded. I'm using a queue to stare the nodes thata can be sum, etc.
The problem I'm facing is this
error: no match for call to ‘(Triplets) (int&, int&, bool&, NodeT*&)’
The code is coming from is this
void find_triplets(NodeT *ptrRoot)
{
if (ptrRoot != NULL)
{
find_triplets(ptrRoot->left);
find_triplets(ptrRoot->right);
cout << "find triplets and save them to the queue" << endl;
cout << " we hit a hot spot is null the root, nothing to see here move along boys" << endl;
if(ptrRoot->left != NULL && ptrRoot->right != NULL)
{
if (ptrRoot->left->done == true && ptrRoot->right->done == true)
{
cout << "we got one of 2 sons true so do something, this are the sons "
<< ptrRoot->left->key_value << " " << ptrRoot->right->key_value << endl;
cout << "sum them and put it in the father and set it to true " << endl;
ptrRoot->key_value = ptrRoot->left->key_value + ptrRoot->right->key_value;
ptrRoot->done = true;
cout << "thread queue " << endl;
triplet(ptrRoot->left->key_value, ptrRoot->right->key_value, ptrRoot->done, ptrRoot);
qThreads.push(triplet);
}
}
}
The triplet class is like so
class Triplets
{
public:
int nVal1;
int nVal2;
NodeT *ptrNode;
bool bUpdate;
Triplets()
{
nVal2 = 0;
nVal1 = 0;
bUpdate = false;
ptrNode = NULL;
}
~Triplets()
{
delete ptrNode;
}
Triplets(int nVal1, int nVal2, bool bUpdate, NodeT *ptrNode)
{
this->nVal2 = nVal2;
this->nVal1 = nVal1;
this->bUpdate = bUpdate;
this->ptrNode = ptrNode;
}
void form_triplet(int nval1, int nVal2, bool bUpdate, NodeT *ptrNode)
{
this->nVal2 = nVal2;
this->nVal1 = nVal1;
this->bUpdate = bUpdate;
this->ptrNode = ptrNode;
}
};
So what I want to do is to store the actual object in the queue to modify it, and don't make copies of it. Thanks
It appears that triplet in your find_triplets function is a Triplets instance. The compiler interprets that line, therefore, as an attempt to invoke its operator() function using those four arguments, but your Triplets class has no such operator, so you get the error message reported above.
You probably meant either to declare another Triplets variable (named triplet), or to call triplet.form_triplet instead of triplet.operator().
Triplets triplet(ptrRoot->left->key_value, ptrRoot->right->key_value, ptrRoot->done, ptrRoot);
// or
triplet.form_triplet(ptrRoot->left->key_value, ptrRoot->right->key_value, ptrRoot->done, ptrRoot);
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).