I've been trying to solve this problem uselessly for a long time... I'll be glad for help.
I have this enum defined:
enum state { empty, black , white , possible};
and these 2 structs:
typedef struct s_node
{
struct s_node* next;
struct s_node* prev;
state color;
int place; //0...63
} ListNode;
and:
typedef struct b_node
{
state color;
ListNode* ptr;
} ArrNode;
and finally class Board:
class Board
{
private:
state turn;
ArrNode board[SIZE][SIZE];
ListNode *head, *tail, *list, *black_end, *white_end;
Possible *possHead;
int black_num, white_num;
friend class Play;
public:
Board(){...}
...
};
I initialize the ListNode with color=empty, and so the ArrNode board.
But when i run the code and about to go through the ListNode I get this:
and when i click the green refresh button i get this:
edit:
here i=19 but i showed board[3][3] (i=27)...
here's a correct snapshot:
But when i step over (F10) it doesn't enter the if condition.
Any help?
Thanks in advance!
edit:
Here's how i initialize ArrNode board[SIZE][SIZE]:
head = new ListNode;
list = head;
for (int i = 0; i < SIZE; i++)
for (int j = 0; j < SIZE; j++)
{
board[i][j].color = empty;
list->next = new ListNode;
list->next->prev = list;
list = list->next;
list->color = empty;
board[i][j].ptr = list;
list->place = i*SIZE + j;
}
list->next = NULL;
Related
First whack at learning pointers, I'm trying to follow all of this and I thought I had it right but alas I am getting a runtime error when calling the append function. The CSV function appears to be working. I'm guessing I've messed up the Append flow. Any tips or advise is warmly welcomed.
struct Car {
string carId; // unique identifier
string title;
};
class LinkedList {
private:
struct node {
Car cars;
node *next; //is this storing the memory address of the struct?
};
// alias for node pointer (memory address of node)
typedef struct node* nodePtr;
// defining pointer variables for memory positions in the List
nodePtr head;
nodePtr curr;
nodePtr temp;
nodePtr tail; //is this needed
public:
LinkedList();
void Append(Car car);
};
//Default constructor
LinkedList::LinkedList() {
head = NULL;
curr = NULL;
temp = NULL;
tail = NULL;
}
void LinkedList::Append(Car car) {
nodePtr n = new node;
n->cars = car;
n->next = NULL;
if (head == NULL){
head = n;
tail =n;
}
else {
tail->next = n;
tail=n;
}
}
void loadCars(string csvPath, LinkedList *list) {
csv::Parser file = csv::Parser(csvPath);
try {
// loop to read rows of a CSV file
for ( unsigned int i = 0; i < file.rowCount(); i++) {
// initialize a bid using data from current row (i)
Car car ;
car.carId = file[i][1];
car.title = file[i][0];
// add this bid to the end
list->Append(car);
}
}
}
int main(int argc, char* argv[]) {
LinkedList carlist
csvPath = xyz;
loadCars(csvPath, &carlist);
}
I had to implement a Linked HashTable for a project. Now I have to come up with an excercise and a solution to it using my hashtable. Everything works just fine, except I get random Segfault errors.
By Random I mean: It is the same line of code that causes it, but always at different times, calls.
I tested my code in Atom, Codeblocks and in Visual Studio Code. Both Atom and CB threw SegFault error, but VS Code ran it just fine without a problem.
NOTE: THIS IS NOT THE FULL/REAL CODE. It's part of a header file that is included in the main.cpp file which is then compiled and ran.
The Code:
#include <iostream>
#include <typeinfo>
#include <string>
using namespace std;
//List:
template<class T>
struct Node
{
string data;
Node *next;
};
class List
{
private:
Node *head, *tail;
int length;
friend class HashTable;
public:
List();
List(const List &L);
//~List() {delete this;};
List& operator =(List L);
int find(string);
void insert(string value);
void remove_head();
void remove_poz(int);
void remove_tail();
void clear();
void display();
};
List::List()
{
head = NULL;
tail = NULL;
length = 0;
}
template<>
string List<string>::findByIndex(int ind)
{
int i = 0;
Node<string>* temp = new Node<string>;
temp = head;
while (temp != NULL)
{
i++;
if (i == ind) return temp->data;
temp = temp->next;
}
delete temp;
return "-1";
}
template<class T>
void List<T>::remove_head()
{
Node<T>* temp = new Node<T>;
temp = head;
head = head->next;
delete temp;
length--;
}
template<class T>
void List<T>::remove_pos(int pos)
{
int i;
Node<T>* curr = new Node<T>;
Node<T>* prev = new Node<T>;
curr = head;
for (i = 1; i < pos; ++i)
{
prev = curr;
curr = curr->next;
}
if (curr)
{
prev->next = curr->next;
length--;
}
else cout << "Error" << endl;
}
template<class T>
void List<T>::remove_tail()
{
Node<T>* curr = new Node<T>;
Node<T>* prev = new Node<T>;
curr = head;
while (curr->next != NULL)
{
prev = curr;
curr = curr->next;
}
tail = prev;
prev->next = NULL;
delete curr;
length--;
}
//HashTable:
class HashTable
{
private:
List *table;
float load, stored;
int slots;
friend class List;
public:
HashTable();
HashTable(int);
~HashTable();
int hashFunc(string key);
int findTable(string);
int findList(string);
HashTable& operator =(const HashTable&);
void resize(); //I need this one
void insert(string);
void remove(string);
void clear(int);
void clear();
void display();
};
HashTable::HashTable()
{
stored = 0;
load = 0.00;
slots = 15;
table = new List[slots];
}
int HashTable::hashFunc(string key)
{
int g, h = 0;
unsigned int i;
for (i = 0; i < key.size(); ++i)
{
h = (h << 4) + (int)(key[i]);
g = h & 0xF0000000L;
if (g != 0)
{
h = h ^ (g >> 24);
}
h = h & ~g;
}
return h % slots;
}
template<class T>
void HashTable<T>::remove(T value)
{
int ind = hashFunc(value);
int findInd = table[ind].findByValue(value);
if (findInd == 0)
table[ind].remove_head();
else if (findInd < table[ind].length)
table[ind].remove_pos(findInd);
else table[ind].remove_tail();
if (table[ind].isEmpty()) occupied--;
stored--;
load = stored / slots;
}
The function that would cause the segfault:
(This would be called over and over again in a loop till I don't have more elements in my table)
string reakcio(HashTable<string>& HT, int tarolok)
{
const int anyagszam = rand() % 4 + 2; //Min 2, Max 5 anyag hasznalodik
int i = 0, j;
string anyagok[5];
string eredmeny;
for(j = 0; j < tarolok && i < anyagszam; ++j) //elemek kivetele
{
while(!HT.table[j].isEmpty())
{
anyagok[i++] = HT.table[j].findByIndex(1); //This line right here is the culprit :(
HT.remove(anyagok[i-1]);
}
}
const int siker = rand() % 4 + 0; //75% esely a sikerre
if (siker)
{
eredmeny = anyagok[0];
for(i = 1; i < anyagszam; ++i)
eredmeny += " + " + anyagok[i];
}
else
eredmeny = "Sikertelen reakcio";
return eredmeny;
}
(Note: only the functions that might be needed are shown here)
Every element of my hashtable, or of my lists is a 10 character long random string value.
srand(time(NULL)) is used before the function call in main.cpp
Any help or advice would be much appreciated, as I'm stuck at this and I really need to move on to the next portion of my exercise, but I can't without this.
The main.cpp file:
#include <iostream>
//#include "LinkedHash.h"
#include "functions.cpp"
int main()
{
HashTable<string> Anyagok;
int tarolok;
tarol(Anyagok); //Stores the data from file, no problem here, functions.cpp
tarolok = Anyagok.getSlots();
srand(time(NULL));
int i = 1;
while (Anyagok.getStored() > 5 )
cout<<reakcio(Anyagok, tarolok)<<" "<<i++<<endl;
return 0;
}
The LinkedHash.h contains the hashtable and the list, the functions.cpp contains the problematic function.
EDIT:
By suggestion I changed out the
Node<string>* temp = new Node<string>;
temp = head;
part to
Node<string>* temp = head;
Also removed the delete line.
But my problem is still the same :/
Everything works just fine, except I get random Segfault errors
Then nothing works at all.
A first review show little care to the cornercases in the list class. You need to define a correct behavior for
operation on empty lists
operation on first and last element
key not found during search
Notable errors found:
remove_head, remove_tail will segfault on empty list. head is NULL. head->next is invalid memory access. Similar errors are all over the implementation.
HashTable<T>::remove(T value) will always remove something. Even if the value argument is not in the hashtable. This is deeply flawed
findByIndex returning "-1" make no sense. "-1" is a valid input.
Node<T>* temp = new Node<T>;temp = head;. You just leaked memory. You need a pointer to manipulate node addresses. You should not instantiate Nodes to get a pointer. This is not an issue (ie not noticeable) for a small projet, but unacceptable for a real implementation.
I'm having an issue I can't figure out how to diagnose. It's been a while since I've worked in C++ and I decided to write a class based implementation of a LLL, with one class for the node and one for the list for the sake of practice. Once the list has been initialized in main, it prompts the user to input the length of the list from within the constructor. Then, for some reason, it hangs up instead of generating the list. I haven't gotten any error codes, and it doesn't seem to be stuck in a loop as best as I can tell. I'm very confused.
Main function:
int main() {
LLL * myList = new LLL();
int displayCount = 0;
displayCount = myList->display();
cout << "\n\n" << displayCount << " nodes were displayed\n\n";
delete myList;
return 0;
}
LLL constructor:
LLL::LLL() {
head = new node(rand() % 20);
node * current = head;
cout << "\n\nHow many nodes would you like this list to be? ";
int length = 0;
cin >> length;
cin.ignore(1000);
for (int i = 1; i <= length; ++i) {
node * temp = new node(rand() % 20);
current->attachNext(temp);
current = temp;
delete temp;
}
Node constructor:
node::node(int data) {
this->next = NULL;
this->data = data;
}
attachNext function:
bool node::attachNext(node *& toAttach) {
this->next = toAttach;
return true;
}
Header file:
#include <iostream>
#include <math.h>
using namespace std;
class node {
public:
node();
node(int data);
~node();
node * traverse();//returns obj->next node
bool checkNext();//returns true if obj->next exists
bool attachNext(node *& toAttach);
int display();
int deleteAll(int & count);
private:
node * next;
int data;
};
class LLL {
public:
LLL();
LLL(int length);
~LLL();
int display();
private:
node * head;
};
Ok, I figured it out. I called the cin.ignore function in the LLL and forgot to specify the delimiter.
This:
cin.ignore(1000);
Should have been:
cin.ignore(1000, '\n');
I was trying to create a linked list using a for loop but the 'new' in the for loop in the create() method didn't quite allocate a new slot to store new data. As a result, when I tried to print the list, I got an infinite loop. Can somebody tell me what's wrong here?
struct node
{
double value;
node * next_ptr;
node(){}
node(double val, node * p): value(val), next_ptr(p) {}
~node(){}
};
node * create()
{
using namespace std;
node temp = {0, nullptr};
node * result;
for(int i=1; i<5; ++i)
{
result = new node;
result->value = i;
result->next_ptr = &temp;
temp = *result;
}
return result;
};
The reason you are probably getting an infinite loop is because in:
temp = *result;
you are copying the value of *result into a new object of type node, which is unrelated to the one you created.
What you want to do is store a pointer instead:
node* temp = nullptr;
node* result;
for(int i=0; i<5; ++i)
{
result = new node;
result->value = i;
result->next_ptr = temp;
temp = result;
}
return result;
Live demo
A part from the learning value, just stick to std::forward_list or std::list, for lists, instead. Or even better just use std::vector or other containers (depending on the use that you make of the container).
a simple one to create linked in for loop
#include <iostream>
class LinkedList {
public:
int value;
LinkedList * next;
};
int main()
{
LinkedList *List = nullptr;
LinkedList *head = List;
LinkedList *prev;
for (int i=0; i< 3;i++)
{
LinkedList *temp = new(LinkedList);
temp->value = i;
temp->next = nullptr;
if (head == nullptr)
{
head = temp;
prev = head;
}
else
{
prev->next = temp;
prev = temp;
}
}
}
I have problem about struct and class. Now I define class inside the struct and then I create the struct as node and push node in queue. The problem is when I pop queue I create the node to receive pop node but the class in node is a new one, not the same as before push. Follow as code.
struct queueNode {
Puzzle puzzle;
queueNode *next;
short lastMove;
};
class Puzzle {
private :
short field[4][4];
short posBlankI;
short posBlankJ;
public :
Puzzle();
bool isFinish();
void print();
void create();
}
class Queue {
private:
queueNode *first, *last;
public:
Queue(){
first = new queueNode;
first->next = NULL;
last = first;
}
~Queue() { delete first; }
bool isEmpty(){ return (first->next == NULL); }
void push(queueNode *aux){
last->next = aux;
last = aux;
}
queueNode pop(){
queueNode *aux = first;
first = first->next;
return *aux;
}
};
//global variable
Queue *q = new Queue();
int main(){
queueNode *root = new queueNode;
root->puzzle.create();
q->push(root);
q->pop().puzzle.print();
return 0;
}
Yes, you can define a class inside a struct. The code sample doesn't do that.
The problem has nothing to do with a class being member of a struct.
The constructor of Queue creates a queue with 1 blank node. q->push(root) inserts the 2nd node at the end. q->pop() returns the copy of the 1st (blank) node, not the 2nd as you expect.
pop return a object not a pointer. A new queueNode is created and its content is copied from *aux. You should modify pop to return a pointer of queueNode.
When you create the Queue, it creates a queueNode using new and puts it into the Queue by default. So when you call pop() it returns that default node you did not configure using create().
I modified your code a bit and got it to compile and run in order to illustrate the point I am making above.(Note: it compiles on VS2010, remove #include "stdafx.h" if you use something else)
Hopefully this helps you see exactly what you are doing.
I would not recommend using the code below in an implementation you care about. Use it as a learning tool only. I suggest separating out your class declarations into separate header files and the implementations into separate CPP files. It helps organize things.
output:
0000
0000
0000
0000
1111
1111
1111
1111
Code:
#include "stdafx.h"
#include <iostream>
class Puzzle {
private :
short field[4][4];
short posBlankI;
short posBlankJ;
public :
Puzzle()
{
for(int i = 0; i<4; i++)
{
for(int j = 0; j < 4; j++)
{
field[i][j] = 0;
}
}
}
bool isFinish();
void print()
{
for(int i = 0; i<4; i++)
{
for(int j = 0; j < 4; j++)
{
std::cout<<field[i][j];
}
std::cout<<std::endl;
}
}
void create()
{
for(int i = 0; i<4; i++)
{
for(int j = 0; j < 4; j++)
{
field[i][j] = 1;
}
}
}
};
struct queueNode {
Puzzle puzzle;
queueNode *next;
short lastMove;
};
class Queue {
private:
queueNode *first, *last;
public:
Queue(){
first = new queueNode;
first->next = NULL;
last = first;
}
~Queue() { delete first; }
bool isEmpty(){ return (first->next == NULL); }
void push(queueNode *aux){
last->next = aux;
last = aux;
}
queueNode pop(){
queueNode *aux = first;
first = first->next;
return *aux;
}
};
//global variable
Queue *q = new Queue();
int main(){
queueNode *root = new queueNode;
root->puzzle.create();
q->push(root);
q->pop().puzzle.print();
q->pop().puzzle.print();
system("Pause");
return 0;
}
Your push adds your node to the end of the internal list. Which isn't empty.
The standard library has queues, lists, and all sorts of nice containers. Use one of those.