Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. ATL / WTL / STL
  4. STL vector of pointers question

STL vector of pointers question

Scheduled Pinned Locked Moved ATL / WTL / STL
questionc++graphicsdockerhelp
10 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mjackson11
    wrote on last edited by
    #1

    I have two vectors holding different classes. The first class contains only data of integer/double type. I can create a vector of the first class, access it, manipulate it, no problems. The second class contains a combination of data and several pointers to allocated storage space. The space is allocated on the fly as needed. The destructor of the class frees the space. The problem arises when adding new instances of the class to the vector. If there isn't enough space in the vector, the vector class clones itself, adds space, and the erases the old vector. Unfortunately in erasing "old" vector, it frees the storage space and the program crashes because the storage pointers are invalid. Creating a vector of pointers to the class solves the problem but would involve a massive re-write of code. Anyone have any suggestions how to handle this? Is there a graceful way to handle pointers inside the class when you don't know when the class will be destroyed by the container?

    _ S 2 Replies Last reply
    0
    • M mjackson11

      I have two vectors holding different classes. The first class contains only data of integer/double type. I can create a vector of the first class, access it, manipulate it, no problems. The second class contains a combination of data and several pointers to allocated storage space. The space is allocated on the fly as needed. The destructor of the class frees the space. The problem arises when adding new instances of the class to the vector. If there isn't enough space in the vector, the vector class clones itself, adds space, and the erases the old vector. Unfortunately in erasing "old" vector, it frees the storage space and the program crashes because the storage pointers are invalid. Creating a vector of pointers to the class solves the problem but would involve a massive re-write of code. Anyone have any suggestions how to handle this? Is there a graceful way to handle pointers inside the class when you don't know when the class will be destroyed by the container?

      _ Offline
      _ Offline
      _Superman_
      wrote on last edited by
      #2

      Having a copy constructor for the second class should solve the problem.

      «_Superman_» I love work. It gives me something to do between weekends.

      1 Reply Last reply
      0
      • M mjackson11

        I have two vectors holding different classes. The first class contains only data of integer/double type. I can create a vector of the first class, access it, manipulate it, no problems. The second class contains a combination of data and several pointers to allocated storage space. The space is allocated on the fly as needed. The destructor of the class frees the space. The problem arises when adding new instances of the class to the vector. If there isn't enough space in the vector, the vector class clones itself, adds space, and the erases the old vector. Unfortunately in erasing "old" vector, it frees the storage space and the program crashes because the storage pointers are invalid. Creating a vector of pointers to the class solves the problem but would involve a massive re-write of code. Anyone have any suggestions how to handle this? Is there a graceful way to handle pointers inside the class when you don't know when the class will be destroyed by the container?

        S Offline
        S Offline
        Stuart Dootson
        wrote on last edited by
        #3

        In addition to Superman's answer - you need to create an assignment operator that manages your memory as well. Something like this:

        class A
        {
        public:
        A(int i) : pi_(new int(i)) {}
        A(const A& a) : pi_(new int(*a.pi_)) {}
        A& operator=(const A& a)
        {
        *pi_ = *a.pi_;
        }
        ~A() { delete pi_; }
        private:
        int* pi_;
        };

        The other way round this is to manage your storage with (for example) Boost shared pointers[^].

        Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

        _ 1 Reply Last reply
        0
        • S Stuart Dootson

          In addition to Superman's answer - you need to create an assignment operator that manages your memory as well. Something like this:

          class A
          {
          public:
          A(int i) : pi_(new int(i)) {}
          A(const A& a) : pi_(new int(*a.pi_)) {}
          A& operator=(const A& a)
          {
          *pi_ = *a.pi_;
          }
          ~A() { delete pi_; }
          private:
          int* pi_;
          };

          The other way round this is to manage your storage with (for example) Boost shared pointers[^].

          Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

          _ Offline
          _ Offline
          _Superman_
          wrote on last edited by
          #4

          When would the assignment operator be used?

          «_Superman_» I love work. It gives me something to do between weekends.

          S 1 Reply Last reply
          0
          • _ _Superman_

            When would the assignment operator be used?

            «_Superman_» I love work. It gives me something to do between weekends.

            S Offline
            S Offline
            Stuart Dootson
            wrote on last edited by
            #5

            Any method that rearranges items in the vector. An example - the erase method (if you erase any except the last element). Consider this example code:

            #include <iostream>
            #include <vector>

            class Test
            {
            public:
            Test() { std::cout << "Test::Test()\n"; }
            Test( Test const& ) { std::cout << "Test::Test( Test const& )\n"; }
            Test& operator=( Test const& ) { std::cout << "Test::operator=( Test const& )\n"; return *this; }
            ~Test() { std::cout << "Test::~Test()\n"; }
            };

            int main (int argc, char const* argv[])
            {
            std::vector<Test> a;
            std::cout << "push_back\n";
            a.push_back(Test());
            a.push_back(Test());
            a.push_back(Test());
            std::cout << "iterator\n";
            std::vector<Test>::iterator it = a.begin();
            ++it;
            std::cout << "erase\n";
            a.erase(it);
            return 0;
            }

            It produces this output (with VS2008):

            push_back
            Test::Test()
            Test::Test( Test const& )
            Test::~Test()
            Test::Test()
            Test::Test( Test const& )
            Test::Test( Test const& )
            Test::~Test()
            Test::~Test()
            Test::Test()
            Test::Test( Test const& )
            Test::Test( Test const& )
            Test::Test( Test const& )
            Test::~Test()
            Test::~Test()
            Test::~Test()
            iterator
            erase
            Test::operator=( Test const& )
            Test::~Test()
            Test::~Test()
            Test::~Test()

            Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

            M _ 2 Replies Last reply
            0
            • S Stuart Dootson

              Any method that rearranges items in the vector. An example - the erase method (if you erase any except the last element). Consider this example code:

              #include <iostream>
              #include <vector>

              class Test
              {
              public:
              Test() { std::cout << "Test::Test()\n"; }
              Test( Test const& ) { std::cout << "Test::Test( Test const& )\n"; }
              Test& operator=( Test const& ) { std::cout << "Test::operator=( Test const& )\n"; return *this; }
              ~Test() { std::cout << "Test::~Test()\n"; }
              };

              int main (int argc, char const* argv[])
              {
              std::vector<Test> a;
              std::cout << "push_back\n";
              a.push_back(Test());
              a.push_back(Test());
              a.push_back(Test());
              std::cout << "iterator\n";
              std::vector<Test>::iterator it = a.begin();
              ++it;
              std::cout << "erase\n";
              a.erase(it);
              return 0;
              }

              It produces this output (with VS2008):

              push_back
              Test::Test()
              Test::Test( Test const& )
              Test::~Test()
              Test::Test()
              Test::Test( Test const& )
              Test::Test( Test const& )
              Test::~Test()
              Test::~Test()
              Test::Test()
              Test::Test( Test const& )
              Test::Test( Test const& )
              Test::Test( Test const& )
              Test::~Test()
              Test::~Test()
              Test::~Test()
              iterator
              erase
              Test::operator=( Test const& )
              Test::~Test()
              Test::~Test()
              Test::~Test()

              Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

              M Offline
              M Offline
              mjackson11
              wrote on last edited by
              #6

              Wow, that explains a lot of the weird performance issues. Constructing large vectors (200-500) entries is what's taking up so much time. I am going with the vector of pointers because de-referencing them is fast compared to copying what can turn into very large classes. I am also reserving enough space so they won't constantly be copying themselves. Thanks very much for the code example, it was very illuminating.

              S 1 Reply Last reply
              0
              • M mjackson11

                Wow, that explains a lot of the weird performance issues. Constructing large vectors (200-500) entries is what's taking up so much time. I am going with the vector of pointers because de-referencing them is fast compared to copying what can turn into very large classes. I am also reserving enough space so they won't constantly be copying themselves. Thanks very much for the code example, it was very illuminating.

                S Offline
                S Offline
                Stuart Dootson
                wrote on last edited by
                #7

                mjackson11 wrote:

                Constructing large vectors (200-500) entries is what's taking up so much time

                Large? That's not large :) I've tended to use vectors of Boost.SharedPointers[^] in the past, so I don't need to worry about deallocation (and also, it's easier to create indices into that vector, as you can just copy and re-sort the vector of smart pointers). That's been good for vectors with upwards of 10000 elements. Another (and probably better) alternative would be a Boost pointer container[^].

                Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                1 Reply Last reply
                0
                • S Stuart Dootson

                  Any method that rearranges items in the vector. An example - the erase method (if you erase any except the last element). Consider this example code:

                  #include <iostream>
                  #include <vector>

                  class Test
                  {
                  public:
                  Test() { std::cout << "Test::Test()\n"; }
                  Test( Test const& ) { std::cout << "Test::Test( Test const& )\n"; }
                  Test& operator=( Test const& ) { std::cout << "Test::operator=( Test const& )\n"; return *this; }
                  ~Test() { std::cout << "Test::~Test()\n"; }
                  };

                  int main (int argc, char const* argv[])
                  {
                  std::vector<Test> a;
                  std::cout << "push_back\n";
                  a.push_back(Test());
                  a.push_back(Test());
                  a.push_back(Test());
                  std::cout << "iterator\n";
                  std::vector<Test>::iterator it = a.begin();
                  ++it;
                  std::cout << "erase\n";
                  a.erase(it);
                  return 0;
                  }

                  It produces this output (with VS2008):

                  push_back
                  Test::Test()
                  Test::Test( Test const& )
                  Test::~Test()
                  Test::Test()
                  Test::Test( Test const& )
                  Test::Test( Test const& )
                  Test::~Test()
                  Test::~Test()
                  Test::Test()
                  Test::Test( Test const& )
                  Test::Test( Test const& )
                  Test::Test( Test const& )
                  Test::~Test()
                  Test::~Test()
                  Test::~Test()
                  iterator
                  erase
                  Test::operator=( Test const& )
                  Test::~Test()
                  Test::~Test()
                  Test::~Test()

                  Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                  _ Offline
                  _ Offline
                  _Superman_
                  wrote on last edited by
                  #8

                  Thanks. That is new information. So if I have 20 object stored in a vector and I delete the first, operator= is called 19 times!!!

                  «_Superman_» I love work. It gives me something to do between weekends.

                  S 1 Reply Last reply
                  0
                  • _ _Superman_

                    Thanks. That is new information. So if I have 20 object stored in a vector and I delete the first, operator= is called 19 times!!!

                    «_Superman_» I love work. It gives me something to do between weekends.

                    S Offline
                    S Offline
                    Stuart Dootson
                    wrote on last edited by
                    #9

                    Yep - that's why rvalue references[^] are being introduced in C++0x - they allow the introduction of 'move semantics', which allows the elimination of unnecessary copies like that.

                    Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                    _ 1 Reply Last reply
                    0
                    • S Stuart Dootson

                      Yep - that's why rvalue references[^] are being introduced in C++0x - they allow the introduction of 'move semantics', which allows the elimination of unnecessary copies like that.

                      Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

                      _ Offline
                      _ Offline
                      _Superman_
                      wrote on last edited by
                      #10

                      I had read about rvalue references and I'm able to admire it more now. Thanks :thumbsup:

                      «_Superman_» I love work. It gives me something to do between weekends.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups