Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα στην παρέα,

 

Προσπαθώντας να έχω ένα εποικοδομητικό(λέμε τώρα :P ) καλοκαίρι ξεκίνησα να ασχολούμαι με c++ που έτσι και αλλιώς θα την βρω μπρόστα μου από χειμώνα.

 

Ξεκίνησα λοιπόν να κάνω μια εργασία στην οποία πρέπει να φτιάξω ένα "φόρουμ".

Ένα φόρουμ αποτελείται από threads και τα threads από posts.

Έχει ενα ερώτημα λοιπόν που ζητάει να εκτυπώνονται όλα τα posts ταξινομημένα ανάλογα τον δημιουργό τους χρησιμοποιώντας ένα δυαδικό δέντρο αναζήτησης του οποίου ο κάθε κόμβος περιέχει μια λίστα από τα posts του δημιουργού καθώς και τον δημιουργό.

Την λίστα την δημιουργήσα από την stl::list και εδώ είναι που έχω πρόβλημα:

Όταν εκτελείται η btree::insert και καλείται push_back στην λίστα που έχει τα posts λαμβάνω αυτό το μήνυμα

 

71861609faff4171a36cb473beb1f619.png

 

το οποίο με τις λίγες γνώσεις μου δεν καταλαβαίνω τι σημαίνει.

Κανένας καλοθελητής;

Το project:Link.png Site: Git

 

Υ.Γ. Πολύ πιθανό να υπάρχουν και άλλα λάθη που δεν έχω βρει ακόμα οπότε μην βαράτε! :rolleyes:

Δημοσ.
if (root == nullptr || δεν έχει σημασία τι άλλο λέει εδώ) {
    root->creatorsPost.push_back(itemToPlace);
    root->creator = itemToPlace.getPoster();
    root->right = nullptr;
    root->left = nullptr;
}

Αν το root είναι null pointer τότε κάνε dereference το null pointer?  :)

 

Υπάρχουν φυσικά πάρα πολλά πράγματα που είναι "λάθος" γενικότερα αλλά δεν έχει νόημα να τα ψειρίζουμε πριν μπεις στη λογική του να γράφεις κώδικα που τουλάχιστον λειτουργεί σωστά.

 

Όπως θα δεις και μόνος σου στη C++ ή θα είσαι πάρα πάρα πάρα πολύ προσεκτικός ή θα τραβάς τα μαλλιά σου μέχρι να μην έχεις άλλα. Αυτό εδώ ήταν πολύ προφανές, μέχρι και ένας άσχετος με τον κώδικα το βρήκε χωρίς να το βάλει σε debugger. Εσύ θα έπρεπε να το είχες βάλει σε debugger κατευθείαν κάνοντας step μία γραμμή κάθε φορά μέχρι που να δεις ότι πας να κάνεις dereference nullptr.

  • Like 2
Δημοσ.
if (root == nullptr || δεν έχει σημασία τι άλλο λέει εδώ) {
    root->creatorsPost.push_back(itemToPlace);
    root->creator = itemToPlace.getPoster();
    root->right = nullptr;
    root->left = nullptr;
}

Αν το root είναι null pointer τότε κάνε dereference το null pointer?  :)

 

Υπάρχουν φυσικά πάρα πολλά πράγματα που είναι "λάθος" γενικότερα αλλά δεν έχει νόημα να τα ψειρίζουμε πριν μπεις στη λογική του να γράφεις κώδικα που τουλάχιστον λειτουργεί σωστά.

 

Όπως θα δεις και μόνος σου στη C++ ή θα είσαι πάρα πάρα πάρα πολύ προσεκτικός ή θα τραβάς τα μαλλιά σου μέχρι να μην έχεις άλλα. Αυτό εδώ ήταν πολύ προφανές, μέχρι και ένας άσχετος με τον κώδικα το βρήκε χωρίς να το βάλει σε debugger. Εσύ θα έπρεπε να το είχες βάλει σε debugger κατευθείαν κάνοντας step μία γραμμή κάθε φορά μέχρι που να δεις ότι πας να κάνεις dereference nullptr.

 

Αρχικά ευχαριστώ μιας και αυτό ήταν η ρίζα του κακού.Αφου διόρθωσα αυτό το πρόβλημα έφτιαξα και ένα λογικό λάθος στην insert και τώρα δουλεύει σωστά(Τουλάχιστον μέχρι 25 posts που μπόρεσα να ελέγξω).

Το λάθος έγινε καθαρά από απροσεξία και απειρία στην C++ μιας και είχα φτιάξει αλλού να γίνεται allocate το treenode αλλά το έσβησα όταν άλλαξα μια δικιά μου υλοποίηση λίστας στην std::list. :wacko:

 

Γιατί list κι όχι vector;

Γιατί ζητάει να είναι λίστα,τώρα θα μου πεις για το πρόβλημα  αυτό το ίδιο θα προκύψει και κανείς δεν θα το ελέγξει ποτέ να δει οτί δεν συμφωνεί με την εκφώνηση απλά εκείνη την στιγμή πήγε το μυαλό απευθείας στην list γιατί διάβασα λίστα.

Δημοσ.

Οταν σου πεταξει το exception (αυτο που εχεις κανει screenshot) πατας break ή ok. Τωρα το προγραμμα σου μπαινει σε debug mode (η οπς λεγεται). Το προγραμμα σου εχει κανει pause ενα πραμα, και δεν τρεχει και ειναι ενεργο.

 

Στο vs θα κανεις split κατω δυο παραθυρα, στο ενα θα εχεις autos, watches locals, στο αλλο ολα τα αλλα.

 

Απο το πρωτο θα εχεις active τα locals η autos, στο αλλο το call stack.

 

Sto callstack θα εχεις κατω κατω την συναρτηση που εσκασε και πανω πανω την το root call την main δηλαδη.

 

Στο callstack θα πατας μια μια τις συναρτησεις απο κατω προς τα πανω, μεχρει να δεις δικο σου κωδικα. Οταν δεις δικο σου κωδικα, τσεκαρε το παραθυρο με τα autos/locals εκει θα δεις τις τιμες που εχουν οι μεταβλξτες σου.

 

Καντο και πες μου γιατι σκαει.

  • Like 1
Δημοσ.
//tree.cpp
//demonstrates binary tree
#include <iostream>
#include <stack>
using namespace std;
////////////////////////////////////////////////////////////////
class Node
{
public:
int iData; //data item (key)
double dData; //data item
Node* pLeftChild; //this node’s left child
Node* pRightChild; //this node’s right child
//-------------------------------------------------------------
//constructor
Node() : iData(0), dData(0.0), pLeftChild(NULL),
pRightChild(NULL)
{ }
//-------------------------------------------------------------
~Node() //destructor
{ cout << "X-" << iData << " "; }
//-------------------------------------------------------------
void displayNode() //display ourself: {75, 7.5}
{
cout << '{' << iData << ", " << dData << "} ";
}
}; //end class Node
////////////////////////////////////////////////////////////////
class Tree
{
private:
Node* pRoot; //first node of tree
public:
//-------------------------------------------------------------
Tree() : pRoot(NULL) //constructor
{ }
//-------------------------------------------------------------
Node* find(int key) //find node with given key
{ //(assumes non-empty tree)
Node* pCurrent = pRoot; //start at root
while(pCurrent->iData != key) //while no match,
{
if(key < pCurrent->iData) //go left?
pCurrent = pCurrent->pLeftChild;
else //or go right?
pCurrent = pCurrent->pRightChild;
if(pCurrent == NULL) //if no child,
return NULL; //didn’t find it
}
return pCurrent; //found it
} //end find()
//-------------------------------------------------------------
void insert(int id, double dd) //insert new node
{
Node* pNewNode = new Node; //make new node
pNewNode->iData = id; //insert data
pNewNode->dData = dd;
if(pRoot==NULL) //no node in root
pRoot = pNewNode;
else //root occupied
{
Node* pCurrent = pRoot; //start at root
Node* pParent;
while(true) //(exits internally)
{
pParent = pCurrent;
if(id < pCurrent->iData) //go left?
{
pCurrent = pCurrent->pLeftChild;
if(pCurrent == NULL) //if end of the line,
{ //insert on left
pParent->pLeftChild = pNewNode;
return;
}
} //end if go left
else //or go right?
{
pCurrent = pCurrent->pRightChild;
if(pCurrent == NULL) //if end of the line
{ //insert on right
pParent->pRightChild = pNewNode;
return;
}
} //end else go right
} //end while
} //end else not root
} //end insert()
//-------------------------------------------------------------
void traverse(int traverseType)
{
switch(traverseType)
{
case 1: cout << "\nPreorder traversal: ";
preOrder(pRoot);
break;
case 2: cout << "\nInorder traversal: ";
inOrder(pRoot);
break;
case 3: cout << "\nPostorder traversal: ";
postOrder(pRoot);
break;
}
cout << endl;
}
//-------------------------------------------------------------
void preOrder(Node* pLocalRoot)
{
if(pLocalRoot != NULL)
{
cout << pLocalRoot->iData << " "; //display node
preOrder(pLocalRoot->pLeftChild); //left child
preOrder(pLocalRoot->pRightChild); //right child
}
}
//-------------------------------------------------------------
void inOrder(Node* pLocalRoot)
{
if(pLocalRoot != NULL)
{
inOrder(pLocalRoot->pLeftChild); //left child
cout << pLocalRoot->iData << " "; //display node
inOrder(pLocalRoot->pRightChild); //right child
}
}
//-------------------------------------------------------------
void postOrder(Node* pLocalRoot)
{
if(pLocalRoot != NULL)
{
postOrder(pLocalRoot->pLeftChild); //left child
postOrder(pLocalRoot->pRightChild); //right child
cout << pLocalRoot->iData << " "; //display node
}
}
//-------------------------------------------------------------
void displayTree()
{
stack<Node*> globalStack;
globalStack.push(pRoot);
int nBlanks = 32;
bool isRowEmpty = false;
cout <<
"......................................................";
cout << endl;
while(isRowEmpty==false)
{
stack<Node*> localStack;
isRowEmpty = true;
for(int j=0; j<nBlanks; j++)
cout << ' ';
while(globalStack.empty()==false)
{
Node* temp = globalStack.top();
globalStack.pop();
if(temp != NULL)
{
cout << temp->iData;
localStack.push(temp->pLeftChild);
localStack.push(temp->pRightChild);
if(temp->pLeftChild != NULL ||
temp->pRightChild != NULL)
isRowEmpty = false;
}
else
{
cout << "--";
localStack.push(NULL);
localStack.push(NULL);
}
for(int j=0; j<nBlanks*2-2; j++)
cout << ' ';
} //end while globalStack not empty
cout << endl;
nBlanks /= 2;
while(localStack.empty()==false)
{
globalStack.push( localStack.top() );
localStack.pop();
}
} //end while isRowEmpty is false
cout <<
"......................................................";
cout << endl;
} //end displayTree()
//-------------------------------------------------------------
void destroy() //deletes all nodes
{ destroyRec(pRoot); } //start at root
//-------------------------------------------------------------
void destroyRec(Node* pLocalRoot) //delete nodes in
{ // this subtree
if(pLocalRoot != NULL)
{ //uses postOrder
destroyRec(pLocalRoot->pLeftChild); //left subtree
destroyRec(pLocalRoot->pRightChild); //right subtree
delete pLocalRoot; //delete this node
}
}
//-------------------------------------------------------------
}; //end class Tree
////////////////////////////////////////////////////////////////
int main()
{
int value;
char choice;
Node* found;
Tree theTree; //create tree
theTree.insert(50, 5.0); //insert nodes
theTree.insert(25, 2.5);
theTree.insert(75, 7.5);
theTree.insert(12, 1.2);
theTree.insert(37, 3.7);
theTree.insert(43, 4.3);
theTree.insert(30, 3.0);
theTree.insert(33, 3.3);
theTree.insert(87, 8.7);
theTree.insert(93, 9.3);
theTree.insert(97, 9.7);
while(choice != 'q') //interact with user
{ //until user types ‘q’
cout << "Enter first letter of ";
cout << "show, insert, find, traverse or quit: ";
cin >> choice;
switch(choice)
{
case 's': //show the tree
theTree.displayTree();
break;
case 'i': //insert a node
cout << "Enter value to insert: ";
cin >> value;
theTree.insert(value, value + 0.9);
break;
case 'f': //find a node
cout << "Enter value to find: ";
cin >> value;
found = theTree.find(value);
if(found != NULL)
{
cout << "Found: ";
found->displayNode();
cout << endl;
}
else
cout << "Could not find " << value << endl;
break;
case 't': //traverse the tree
cout << "Enter traverse type (1=preorder, "
<< "2=inorder, 3=postorder): ";
cin >> value;
theTree.traverse(value);
break;
case 'q': //quit the program
theTree.destroy();
cout << endl;
break;
default:
cout << "Invalid entry\n";
} //end switch
} //end while
return 0;
} //end main()

Αυτός είναι ωραίος κώδικας για beginners για να καταλάβουν τα δέντρα.. από το βιβλίο που διάβαζα.. πάρτο κομμάτι κομμάτι και μετά θα μπορείς να πάς σε πιό περίπλοκα πιό εύκολα.. θέμα εξοικίωσης είναι.. άμα έχεις καταλάβει τους pointers μην μασας..

Εγώ βασικά τον έχω μάθει απέξω χωρίς να το θέλω.. :)  

Δημοσ.

Το θέμα δεν ήταν με τα δέντρα :)

 

Παπι ευχαριστώ για τον debugger μιας και τώρα το γύρισα σε vs από c::b και ακόμα το μαθαίνω. Το λάθος ήταν απλά απροσεξίας και βλακείας δικιάς μου

Δημοσ.

Το θέμα δεν ήταν με τα δέντρα :)

 

Παπι ευχαριστώ για τον debugger μιας και τώρα το γύρισα σε vs από c::b και ακόμα το μαθαίνω. Το λάθος ήταν απλά απροσεξίας και βλακείας δικιάς μου

Η γνώμη μου είναι να δοκιμάσεις και άλλα IDE. Π.χ. eclipse.

Δημοσ.

Η γνώμη μου είναι να δοκιμάσεις και άλλα IDE. Π.χ. eclipse.

Το clion δοκιμάζω και η αληθεια είναι ότι μου αρέσει πολύ περισσότερο και δεν ξέρω σε ποιο να επενδυσω χρόνο μιας και υποτίθεται ότι το vs χρησιμοποιείται πιο πολύ.

Δημοσ.

Δεν θα το έλεγα για το VS.

 

 

Μην ξεχνάς ότι το VS είναι μόνο για Windows. Πόσες εταιρίες θαρρείς ότι (πλέον) δουλεύουν με τεχνολογίες MS και όχι με open source; Για Ελλάδα δεν μπορώ να σου πω, αλλά σε Β. Ευρώπη το σενάριο είναι: Είτε Linux και universal/web apps/services είτε MAC OS και desktop apps ή Mobile Apps με X-platform tools και apple tools. Το Windows είναι εντελώς μειοψηφία.

 

Ένας από τους λόγους είναι και τα λεφτά που θέλεις για να το αγοράσεις plus τα λεφτά για τις άδειες του λογισμικού (π.χ. VS vs XCode, JetBrains tools, Eclipse κτλ).

 

 

Η γνώμη μου είναι καθαρά NO NO VS αλλά yes yes σε JetBrains. Επειδή δεν έχουν (από όσο θυμάμαι) IDE για C++, τότε η επόμενη εναλλακτική είναι Eclipse.

Δημοσ.

Δεν θα το έλεγα για το VS.

 

 

Μην ξεχνάς ότι το VS είναι μόνο για Windows. Πόσες εταιρίες θαρρείς ότι (πλέον) δουλεύουν με τεχνολογίες MS και όχι με open source; Για Ελλάδα δεν μπορώ να σου πω, αλλά σε Β. Ευρώπη το σενάριο είναι: Είτε Linux και universal/web apps/services είτε MAC OS και desktop apps ή Mobile Apps με X-platform tools και apple tools. Το Windows είναι εντελώς μειοψηφία.

 

Ένας από τους λόγους είναι και τα λεφτά που θέλεις για να το αγοράσεις plus τα λεφτά για τις άδειες του λογισμικού (π.χ. VS vs XCode, JetBrains tools, Eclipse κτλ).

 

 

Η γνώμη μου είναι καθαρά NO NO VS αλλά yes yes σε JetBrains. Επειδή δεν έχουν (από όσο θυμάμαι) IDE για C++, τότε η επόμενη εναλλακτική είναι Eclipse.

Έβγαλαν *πρόσφατα* και λέγεται Clion. Ουσιαστικά είναι σαν το resharper αλλά με τα καλουδια της jetbrains. Ένα ακόμα θετικό είναι ότι μπορείς να χρησιμοποιήσεις ότι compiler θέλεις. (βέβαια έχει ακόμα bugs τα οποία εμένα δεν με επηρεάζουν στο επίπεδο που είμαι)

Δημοσ.

Για όσους έχουν φοιτητικό email όλα τα προϊόντα της Jetbrains είναι free. Οπότε κοιτάτε κατα κει. Εμένα με ξένισε αρκετά το RubyMine που δοκίμασα, προτιμώ editors. 

Βέβαια δεν το έψαξα και πολύ να το φέρω στα μέτρα μου γιατί δεν είχα χρόνο, αν βρω χρόνο θα δώσω πιο extensive look, μήπως και με βολέψει καλύτερα.

  • Like 1
Δημοσ.

Για όσους έχουν φοιτητικό email όλα τα προϊόντα της Jetbrains είναι free. Οπότε κοιτάτε κατα κει. Εμένα με ξένισε αρκετά το RubyMine που δοκίμασα, προτιμώ editors.

Βέβαια δεν το έψαξα και πολύ να το φέρω στα μέτρα μου γιατί δεν είχα χρόνο, αν βρω χρόνο θα δώσω πιο extensive look, μήπως και με βολέψει καλύτερα.

Ναι εννοείται και αυτό αλλά και γενικά άμα βγάζεις λεφτά και δεν το κάνεις από χόμπι τα 5-15 ευρώ το μήνα είναι ελάχιστα άμα είναι χρήσιμο εργαλείο. Εδώ δίνεις πχ τόσα για μουσική Spotify.

Δημοσ.

Ναι εννοείται και αυτό αλλά και γενικά άμα βγάζεις λεφτά και δεν το κάνεις από χόμπι τα 5-15 ευρώ το μήνα είναι ελάχιστα άμα είναι χρήσιμο εργαλείο. Εδώ δίνεις πχ τόσα για μουσική Spotify.

That. Το κακό είναι ότι είναι per year το subsciption. Τώρα που το έχω βάλει να το δω, έχω βρει πολλά +, αλλά είναι άσχημο γαμώτο. Δεν μπορώ, πονάνε τα μάτια μου.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...