2010-10-07 13 views
0

我有以下代碼,它應該將線程A的shared_ptr實例添加到入侵鏈接列表中。其他消費者線程隨後會將其從名單。然而,在某個時候,我的shared_ptr似乎被破壞,並且在鏈接列表中對它的引用不再有效,導致Assert。shared_ptr在我可以正確使用前被破壞

有人能告訴我我做錯了什麼嗎?我懷疑這是因爲我在本地範圍內創建了原始的shared_ptr,並且它被破壞了。雖然名單應該仍然有一個參考? (這不是生產代碼)

編輯:

使用的變量

Defintiions:

BaseHookQueueList* lst; 
typedef boost::intrusive::list<QueueList> BaseHookQueueList; 
class QueueList : public boost::intrusive::list_base_hook<> 


// Making my BaseHookQueueList take a shared_ptr of pointing to type QueueList conflicts // with the list_base_hook because it does not seem to like shared_ptr... 
    //////////////////////////////////////////////////////////////////////////////////// 
     if (dwWait == WAIT_OBJECT_0) //Wait is successfull 
        { 
         while(count != 100) 
         { 
          //Some new request arrived 
          boost::shared_ptr<QueueList> Qlist (new QueueList()); //Create shared_ptr instance 
          int temp = 0; 
          if (count > 5) 
          { 
           Qlist->SetName(names[temp]); // Fill up name property of QueueList object with some nonsense... 
           temp++; 
          } 
          else 
          { 
           Qlist->SetName(names[count]); 
          } 

          workerfunc(lst, Qlist); // Pass to worker func 
          count++;  
         } 
        } // shared_ptr goes out scope and I get ASSERT error from list!! 
       } 
     } 

     void workerfunc(BaseHookQueueList* l, LIST item) // LIST is a typedef shared_ptr<QueueList> LIST 
     { 
      { 
       boost::mutex::scoped_lock workerfunclock(listlock); 

       l->push_front(*item); //Add to list 
      } 

      //Scope of lock 
      { 
       boost::mutex::scoped_lock workerfuncconsoleLock(consolelock); 
       printf("Adding item to list...\n"); 
      } 

      ReleaseSemaphore(hConsumer, 1, NULL); // Set conumser Semaphore to Signalled with number of items currently on the queue 
     } 
+0

我猜'LIST'是一個typedef,但是是什麼?另外,什麼是'lst'? – ereOn 2010-10-07 12:41:36

+0

typedef shared_ptr LIST; – 2010-10-07 12:48:22

+1

發佈代碼時,如果您管理縮進以便大多數(如果不是全部)代碼和註釋都可以在不進行水平滾動的情況下看到,則會有所幫助。 – 2010-10-07 13:19:49

回答

3

如果BaseHookQueueList像你說的那樣是一個入侵列表,那麼你應該記住,入侵列表並不佔用對象的所有權。在這種情況下,你的共享指針擁有所有權,當它們被銷燬時,對象也被銷燬。

編輯:而不是干擾列表你可以使用容器,如std :: list或std :: queue,可以包含智能指針。

+0

但std :: list將對象的副本放到列表中時會產生副本,如果列表中有很多對象,是不是會產生很多開銷? – 2010-10-07 13:17:36

+1

如果你的列表包含'shared_ptr',那麼代價就是複製共享指針,它是* small *(複製了幾個指針並更新了引用計數) – 2010-10-07 13:24:53

+0

@David:小,但確實觸發了一些引用+訪問共享資源(計數器)。如果''shared_ptr'已經由'make_shared'創建,則會減少。 – 2010-10-07 13:35:49

2

在你的工人功能,你存儲所指向的項目,而不是共享指針,所以共享指針的引用計數不會增加。

0

我猜項目在這種情況下是錯誤的。 由於運營商會返回對您的類型的引用。所以你把一個const ref放入你的列表中,但不是shared_ptr的一個副本。

4
l->push_front(*item); //Add to list 

解除引用可能是問題所在。您沒有將shred_ptr實例傳遞給l列表,但指向對象本身。如果不是這樣,請發佈更完整,更少混淆的測試用例。