Could I define class inside struct in c++ - c++

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.

Related

linked list with data in null node

i want to make a linked list ..
but the first node with a data and null link
if i input a string (123)
linked list be like this:
1/null - 2/point to the last one(1) - 3/point to the last one(2)
#include <iostream>
#include <string>
using namespace std;
struct link
{
int data;
link* next;
};
class LinkedList
{
private:
link* first;
public:
LinkedList(){}
void Add(string s)
{
for (int i = 0; i > s.length(); i++)
{
if (i == 0)
{
first->data = s[i];
first->next = NULL;
}
else
{
link* NewOne = new link;
NewOne->data = s[i];
NewOne->next = first;
first = NewOne;
}
}
}
void display()
{
cout << first->data;
}
};
int main()
{
LinkedList l1;
l1.Add("2734");
l1.display();
return 0;
}
what's the wrong in the code
You forget to allocate memory for first.
Following may help (using std::unique_ptr for free/correct memory management):
struct link{
char data;
std::unique_ptr<link> next;
};
class LinkedList {
private:
std::unique_ptr<link> first;
public:
void Set(const std::string& s){
for (auto c : s) {
std::unique_ptr<link> node = std::move(first);
first = std::make_unique<link>();
first->data = c;
first->next = std::move(node);
}
}
Live example
It also looks like you're storing characters in an int. Your output will be the ASCII value of the character rather than the raw int values.
I would recommend using unique pointers as Jarod42 has done. Having said that, this quick example below does not use them so you will need to call delete appropriately or use unique_ptr.
I added a last pointer to help traversal of the list as we make new links.
private:
Link * first;
Link *last;
int numLinks;
public:
LinkedList()
{
first = NULL;
last = NULL;
numLinks = 0;
}
Now for Add
void Add(string s)
{
for (int i = 0; i < s.length(); i++)
{
if (numLinks == 0)
{
first = new Link;
first->data = (s[i] - '0');
first->next = NULL;
last = first;
numLinks++;
}
else
{
Link * newLink = new Link;
newLink->data = (s[i] - '0');
newLink->next = NULL;
last->next = newLink;
last = newLink;
numLinks++;
}
}
}
The constructor does not initialize the first member. Subsequently, in Add():
for (int i = 0; i > s.length();i++){
if (i == 0){
first->data = s[i];
first->next = NULL;
}
This ends up dereferencing an uninitialized pointer, leading to undefined behavior.
There's also a problem with your display() too, but this is the main problem.

Creating Linked List using For Loop (c++)

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;
}
}
}

Creating objects dynamically c++

Well, i've read many different posts about this topic, but none could solve my question.
How can i dynamically create objects, and store them in a linked list.
i've this code that an object saves a number, and then it has a pointer that points to the next number, for representation only.
For example: 17
One->next = seven. Boths are objects of the same class.
class Class{
private:
int value;
Class *pNext; //Points to the next object in the linked list.
public:
Class(){value = 0; }
~Class(){;}
void setV(int x){ value = x;}
int getV(){return value;}
//void setP(Class *p){ pNext = p;} ?? Is this right?
};
int main(){
Class *pFirst; //pointer to first element
Class *pLast; //pointer to last element
Class *pCurrent; //pointer to current element
for(int i = 0; i < 4;i++){
pCurrent = new Class;
pCurrent->setV(i);
//pCurrent->setP(NULL);
}
for(int i = 0; i < 4;i++){
cout << pCurrent->getV() << " ";
}
return 0;
}
Thanks
To make the list permanent, you first have to declare your head node and then for each iteration in your for loop, add on to that list.
int main()
{
Class *pFirst; //pointer to first element
pFirst->setV(0);
Class *pLast; //pointer to last element
Class *pCurrent; //pointer to current element
pFirst->pNext = pCurrent; // To keep track of the list via head
for(int i = 0; i < 4;i++)
{
pCurrent = new Class;
pCurrent->setV(i);
pCurrent->pNext = NULL;
}
for(int i = 0; i < 4;i++)
{
cout << pCurrent->getV() << " ";
}
return 0;
}

compiler isn't recognizing a value in a struct

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;

application keeps receiving segmentation fault - except if i add a for loop

Hi everyone: Here i have created a queue from two stacks: You add to the one and remove from the other - when you want to remove the first stack dumps all its data into the second one, and it works perfectly - BUT
whenever i try to execute this loop without the bottom for loop or cin
the program receives a segmentation fault, i mean the most bottom for loop doesn't even execute but take it out and see what happens. Could this be some sort of buffer overflow
and Gcc needs time to manage the memory?
=====================================================================
struct Node
{
int DataMember;
Node* Next;
};
class Que
{
public:
Que();
~Que();
void Add(int);
void Pop();
int getSize();
void Purge();
private:
Node* Head;
bool StackOrQue; //True = Que False = Stack
int Size;
int Remove();
void Reverse();
};
void Que::Purge()
{
while(Head != NULL)
Pop();
if(StackOrQue)
StackOrQue = false;
}
int Que::getSize()
{
return Size;
}
Que::Que()
{
Head = NULL;
Size = 0;
StackOrQue = false;
}
Que::~Que()
{
Head = NULL;
}
void Que::Add(int q)
{
if(StackOrQue)
Reverse();
Size += 1;
Node* Temp = new Node;
Temp->DataMember = q;
Temp->Next = Head;
Head = Temp;
}
int Que::Remove()
{
int i = Head->DataMember;
Node* Temp = Head->Next;
delete Head;
Size -= 1;
Head = Temp;
return i;
}
void Que::Pop()
{
if(!StackOrQue)
Reverse();
cout << Remove();
}
void Que::Reverse()
{
Que TempStack;
int k = Size;
for(int i = 0; i < k; i++)
TempStack.Add(this->Remove());
delete this;
*this = TempStack;
if(!StackOrQue)
StackOrQue = true;
else
StackOrQue = false;
}
=====================================================================
Que q;
char a = NULL;
while(a != 'x')
{
q.Purge();
q.Add(1);
q.Add(2);
q.Add(3);
q.Add(4);
q.Add(5);
q.Add(6);
q.Add(7);
q.Add(8);
int size = q.getSize();
for(int i = 0; i < size; i++)
q.Pop();
//cin >> a;
for(int i = 0; i < 0; i++)
;
}
Thanks in-advance
delete this;
*this = TempStack;
There are some extreme corner cases in which delete this; actually does the right thing. This is not one of them. Specially since your Queue is placed in the stack, and you further try to delete it. If you intend to call the destructor instead do this->~Queue(), however after a manual destruction the only sensible thing to do next is a placement new. Assigning to *this is almost always a bad idea (if you bring inheritance into the picture, you have just caused a slice object to be created and more problems ahead the road). Also, your class should be implementing a copy constructor and an assignment operator, to correctly handle the resources allocated.