Thread: Tree of different items

  1. #16
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Do not worry, I do not copy paste code, I judge it and get inspired!
    This code - I have not run it - seems to work, but shouldn't we free what we allocated?

    Here is the code with the delete operations. I think it's ok, if not let me know!

    Code:
    #include <iostream>
    #include <vector>
     
    typedef std::vector<int> VECTOR;
     
    VECTOR nullVector;
     
    class Node {
    public:
        virtual Node*   getLeft()         = 0;
        virtual Node*   getRight()        = 0;
        virtual void    setLeft(Node* n)  = 0;
        virtual void    setRight(Node* n) = 0;
        virtual VECTOR& vec()             = 0;
        virtual void    print()           = 0;
        virtual void freeTree()           = 0;
    };
      
    class Inner : public Node {
        Node* pleft;
        Node* pright;
    public:
        Inner() : pleft(0), pright(0) { }
        Node*   getLeft()         { return pleft;  }
        Node*   getRight()        { return pright; }
        void    setLeft(Node* n)  { pleft  = n; }
        void    setRight(Node* n) { pright = n; }
        VECTOR& vec()             { return nullVector; } // needs to return something
        void    print();
        void freeTree() {
            if (getLeft())  getLeft()->freeTree();
            if (getRight()) getRight()->freeTree();
            delete this;
        }
    };
     
    void Inner::print() {
        std::cout << "Inner\n";
        if (getLeft())  getLeft()->print();
        if (getRight()) getRight()->print();
    }
      
    class Leaf : public Node {
        VECTOR v;
    public:
        Node*   getLeft()         { return 0; }
        Node*   getRight()        { return 0; }
        void    setLeft(Node* n)  { }  // unused parameter warning
        void    setRight(Node* n) { }  // ditto
        VECTOR& vec()             { return v; }
        void    print();
        void freeTree() {
            delete this;
        }
    };
     
    void Leaf::print() {
        for (size_t i = 0; i < v.size(); i++)
            std::cout << v[i] << ' ';
        std::cout << '\n';
    }
     
    int main() {
        Node* root = new Inner;
     
        root->setLeft(new Inner);
        root->setRight(new Inner);
     
        Node* node = root->getLeft();
     
        node->setLeft(new Leaf);
        node->setRight(new Leaf);
     
        node->getLeft()->vec().push_back(1);
        node->getLeft()->vec().push_back(2);
        node->getLeft()->vec().push_back(3);
     
        node->getRight()->vec().push_back(4);
        node->getRight()->vec().push_back(5);
        node->getRight()->vec().push_back(6);
     
        node = root->getRight();
     
        node->setLeft(new Leaf);
        node->setRight(new Leaf);
     
        node->getLeft()->vec().push_back(7);
        node->getLeft()->vec().push_back(8);
        node->getLeft()->vec().push_back(9);
     
        node->getRight()->vec().push_back(10);
        node->getRight()->vec().push_back(11);
        node->getRight()->vec().push_back(12);
     
        root->print();
     
        root->freeTree();
        return 0;
    }
    Of course, since we are in an OOP environment, this can be modified more.

    Thanks again Canada guy
    Last edited by std10093; 09-02-2013 at 04:29 PM.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  2. #17
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    but shouldn't we free what we allocated?
    Good point. Of course, the memory is (or should be) returned to the system when the process terminates anyway, but it's good practice to delete the elements yourself.

    I'm not sure if your solution is entirely correct. Can an object safely delete itself?

    This might be safer (a function that's not part of any object) :
    Code:
    void DeleteTree(Node *tree) {
        if (!tree) return;
        DeleteTree(tree->getLeft());
        DeleteTree(tree->getRight());
        delete tree;
    }
    And you need to add a virtual destructor to Node:
    Code:
        virtual ~Node() { }  // does nothing, but necessary
    And you can eliminate the "unused parameter" warnings for setLeft and setRight in Leaf like this:
    Code:
        void    setLeft(Node* n)  { (void)n;  }  // avoid unused parameter warning
        void    setRight(Node* n) { (void)n;  }
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #18
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Yes, I like your delete function more. However, in my code it crashes, even thought it prints what it needs to print. Got to find the bug! Ciao!
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  4. #19
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    But if I do it the way I tried before, it won't crash. It's actually an octree and my functions are these: (they are really dirty at the moment, beware )
    Code:
    class Pointer {
    public:
        virtual Point3d& split()                           = 0;
        virtual const Point3d& split() const = 0;
        virtual Pointer** child() = 0;
        virtual const Pointer** child() const = 0;
        virtual std::vector<int>& relevantH() = 0;
        virtual const std::vector<int>& relevantH() const = 0;
        virtual TYPE type() const = 0;
        virtual void    print()           = 0;
        virtual void freeTree()           = 0;
    };
    
    class Node : public Pointer {
        // Private members
        Point3d splitPoint;                  // Split point
        Pointer* childArray[1<<Dimension];   // Pointers to children
    public:
        virtual const Point3d& split() const {return splitPoint;}
        virtual Point3d& split() {return splitPoint;}
        virtual Pointer** child() {return childArray;}
        virtual const Pointer** child() const {return (const Pointer**)childArray;}
        virtual std::vector<int>& relevantH() {}
        virtual const std::vector<int>& relevantH() const {}
        virtual TYPE type() const {return TYPE_INNER;}
        void print() {
            if (child()[0])  child()[0]->print();
            std::cout << "Inner\n" << split();
            if (child()[1])  child()[1]->print();
            if (child()[2])  child()[2]->print();
            if (child()[3])  child()[3]->print();
            if (child()[4])  child()[4]->print();
            if (child()[5])  child()[5]->print();
            if (child()[6])  child()[6]->print();
            if (child()[7])  child()[7]->print();
        }
        
        void freeTree() {
            if (child()[0])  child()[0]->freeTree();
            if (child()[1])  child()[1]->freeTree();
            if (child()[2])  child()[2]->freeTree();
            if (child()[3])  child()[3]->freeTree();
            if (child()[4])  child()[4]->freeTree();
            if (child()[5])  child()[5]->freeTree();
            if (child()[6])  child()[6]->freeTree();
            if (child()[7])  child()[7]->freeTree();
            delete this;
        }
    };
    
    class Leaf : public Pointer {
        // Private members
        std::vector<int> relevantHalfspaces;        // Relevant halfspaces to leaf
    public:
        /**
         * Constructor of Leaf.
         * @param t - size of member vector of leaf
         */
        Leaf(const size_t& t, std::vector<int> relH) : relevantHalfspaces(relH) {
            // In order to avoid multiple re-allocations
            relevantHalfspaces.reserve(t);
            // Use only if compiler supports C+11 features. We reserve space,
            // we do not create 2*V - 4 objects, but if we do not use all the
            // space, it will wait to be allocated, unless we shrink_to_fit.
            // relevantHalfspaces.shrink_to_fit(); <-- This is the line of code.
        }
        virtual const Point3d& split() const {}
        virtual Point3d& split() {}
        virtual Pointer** child() {return 0;}
        virtual const Pointer** child() const {return 0;}
        virtual std::vector<int>& relevantH() {return relevantHalfspaces;}
        virtual const std::vector<int>& relevantH() const {return relevantHalfspaces;}
        virtual TYPE type() const {return TYPE_LEAF;}
        void print() {
            std::cout<<"Leaf\n";
            for( std::vector<int>::const_iterator it = 
                    relevantHalfspaces.begin(); it != relevantHalfspaces.end(); ++it)
                std::cout << *it << ' ';
            std::cout << std::endl;
        }
        void freeTree() {
            delete this;
        }
    };
    is it safe? Does it delete the tree?

    Run it on Linux too and it was ok!

    I tried to use valgrind, like this:
    linux06:/home/users/std10093/splitReduce>% valgrind --tool=memcheck --leak-check=yes run vertices.txt
    %: Too many arguments.
    linux06:/home/users/std10093/splitReduce>% valgrind --tool=memcheck --leak-check=yes ./run vertices.txt
    %: Too many arguments.

    I tried like this too
    g++ main.cpp valgrind --leak-check=yes run vertices.txt
    g++: error: valgrind: No such file or directory
    g++: error: unrecognized option '--leak-check=yes'
    Last edited by std10093; 09-02-2013 at 06:03 PM.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  5. #20
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Hopefully one of the C++ gurus will let us know if it's safe to delete in that way.
    I await their pronouncement.

    About valgrind, is your program called run? Try this:
    valgrind --leak-check=yes progname args...
    (memcheck is the default tool)
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #21
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Me too.

    Here you go
    valgrind --leak-check=yes run vertices.txt
    valgrind: Command not found.

    run is the executable and vertices.txt the cmd arg

    However, valgrind seems to exist
    linux06:/home/users/std10093/splitReduce>locate valgrind
    /usr/lib/valgrind
    /usr/lib/valgrind/python.supp
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  7. #22
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Doesn't it need to be in your bin?

    What does "which valgrind"give you?

  8. #23
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    >which valgrind
    valgrind: Command not found.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  9. #24
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Ooh, that's your problem right there.

    Here's my output:
    $ which valgrind
    /usr/bin/valgrind

    In Linux, everything that's stored in your bin has an automatic alias of the same name.

    Which version of Linux are you running?

    I only ask because each distro should have its own package manager and it's easiest to install stuff through the native manager.

    In Ubuntu, I think the command is "sudo apt-get install valgrind".

    In Arch, it's "sudo pacman -S valgrind".

    You need to find out which distro you're on and use the package manager to install it or if you want, you can download the valgrind source and I think to install from source, it's the following commands :

    ./configure
    make
    make install

  10. #25
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    I can not install anything, because I connect via putty in the lunix lab of my uni
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  11. #26
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Actually, that's where you're wrong!

    You can install anything in Linux as a non-root user just so long as you install it to a directory you are allowed access to.

    All you have to do is change ./configure to this :

    ./configure --prefix=/folder/to/install/to

    and then just choose a directory where you have permission. That's how I installed Gadget-2 on my school's supercomputer.

    Oh, and if it's not -- then it's -. I can't remember if it's one or two hyphens lol XD

  12. #27
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    I emailed the admins. They have told us not to install anything, so I will stick to that order. It won't harm to wait one day or two.
    Meanwhile, one can take a look at my code above and tell if this is safe and if deletes all the tree.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  13. #28
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    XD

    Just try it anyway.

    You won't be doing anything illegal or anything. They give you as the user permissions. Just so long as you don't violate those permissions (which you'll quickly discover anyway), you're fine because you're not doing anything they didn't want you to do in the first place.

    And honestly, any university that doesn't have valgrind available for all users from the start is pretty fail, Imo.

  14. #29
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    We had it, but recently they upgraded the lab and might done something wrong with her.
    My university is the best in Greece, when it comes to informatics.

    And had make the top 100 some years ago, but this is not our case now. Thanks anyway!
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  15. #30
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Oh come on, at least try so I know if I gave correct advice or not!

    I'd like to know if my Linux experience has been useful or not.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 08-01-2007, 01:08 PM
  2. Replies: 5
    Last Post: 12-02-2006, 11:03 AM
  3. Tree-view bold items
    By mobazr in forum Windows Programming
    Replies: 3
    Last Post: 03-14-2005, 08:45 AM
  4. display tree data in binary tree format
    By xddxogm3 in forum C++ Programming
    Replies: 4
    Last Post: 12-11-2003, 12:47 AM
  5. Replies: 5
    Last Post: 05-23-2003, 01:11 PM