Thread: Help with polymorphism and arrays.

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    42

    Help with polymorphism and arrays.

    I'm writing a thread pool class containing the following:
    Code:
    class ThreadPoolWorker {
       friend class ThreadPool ; 
       public:
         virtual int initialize()  = 0 ;
         virtual int finalize()    = 0 ; 
      private:
       pthread_t          tid_;
       pthread_attr_t  attr_;
    } ;
    
    class ThreadPoolJob {
      public:
          virtual int run( ThreadPoolWorker* wrk)  = 0 ;  // pure virtual function
    };
    
    
    class ThreadPool {
    public: 
              int    start( ThreadPoolWorker *tpw, int threads) ;      // Creates threads
              bool add_work( ThreadPoolJob* job) ;               // Put work onto the Q
    
    private:
              static int                     thread(void*) ;       // thread 
              ThreadPoolWorker*    twork;                   // array of workers
    };
    And the main code from the user perspective
    Code:
    // user classes 
    class UserThreadWorker : ThreadPoolWorker {
            public:
                  int initialize ( ) {  
                                        data = 5; ;
            private:
                        int data;
    };
    
    int
    main() {
             
              UserThreadWorker utw[5];
              ThreadPoolWorker* tpw = utw;
              ThreadPool tp;             
    
              tp.start(tpw, 5) ;
    
    }

    Now here is where I've traced the problem too.
    &tpw[1] does not equal &utw[1].


    Internally the start code uses loops through the tpw parameters accessing
    and accesses the tpw[i] variable. But the second element address is off in the array
    causing a segmentation violation when calling tpw[i]->initialize() ;

    Are there any simple ways to correct this?

    My goal is that the workers will have private data that will be utilized in the threads,
    Threads will remain active, but will not do anything until work is posted into the ThreadPool.

    Thanks for any suggestions.
    Ken

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Arrays aren't polymorphic, and you're seeing the result of trying to make them so.

    You need a container of pointers (a smart pointer like the std::tr1::shared_ptr might be a good option). The pointers would be base class pointers, so utw would actually be an array of ThreadPoolWorker* (or shared_ptr<ThreadPoolWorker>). You'd have to use new to create each derived class element and delete to destroy them and free up the memory (or let the smart pointer automatically destroy them). You'd also have to update your start code to handle a container of pointers rather than objects.

    Once you make those changes, though, you should get what you're looking for.

  3. #3
    Registered User
    Join Date
    Aug 2007
    Posts
    42
    Thanks Daved, that helped.

    I did not know arrays where not polymorphic.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You're welcome. Further reading...

    [21] Inheritance -- proper inheritance and substitutability, C++ FAQ Lite

    and

    What's wrong with arrays?

    Plus there are sections about not treating arrays polymorphically in C++ Coding Standards, Effective C++ and More Effective C++.
    Last edited by Daved; 04-13-2009 at 06:04 PM.

Popular pages Recent additions subscribe to a feed