2015-05-24 73 views
2

我查看了boost::hold_any文件,發現了一些讓我困惑的東西。如果我考慮通過我的問題的答案得到的信息:What happens if you call a destructor and use the allocated memory again for other objects?(在Mike Seymour的回答中),那麼操縱未釋放和重新分配的對象的內存是「禁止的」,以便放置一個新的不同類型的對象。boost :: hold_any構造函數是否有未定義的行爲?

我一直認爲boost庫符合標準,但如果我不是完全錯誤的,那麼boost::hold_any會在它的內容指針(void* object)本身的內存中存儲小對象或變量,這會破壞我在前面提到的答案。

那麼我是錯的還是boost::hold_any打破標準?如果我錯了,我的錯誤在哪裏?

或者如果我是對的,如果boost庫包含可能導致未定義行爲的部分,那麼boost庫的可靠程度如何?我知道增強開發者通常知道他們在做什麼,但是我經常聽到未定義的行爲必須在所有條件下避免,所以我有點好奇。

編輯 我改變了代碼示例顯示,舊內容definitly被銷燬!

這是boost::hold_any代碼,我得到了我的信息的要點之一:

template <typename T> 
    basic_hold_any& assign(T const& x) 
    { 
     // are we copying between the same type? 
     spirit::detail::fxn_ptr_table<Char>* x_table = 
      spirit::detail::get_table<T>::template get<Char>(); 
     if (table == x_table) { 
     // if so, we can avoid deallocating and re-use memory 
      table->destruct(&object); // first destruct the old content 
      if (spirit::detail::get_table<T>::is_small::value) { 
       // create copy on-top of object pointer itself 
       new (&object) T(x); 
      } 
      else { 
       // create copy on-top of old version 
       new (object) T(x); 
      } 
     } 
     else { 
      if (spirit::detail::get_table<T>::is_small::value) { 
       // create copy on-top of object pointer itself 
       table->destruct(&object); // first destruct the old content 
       new (&object) T(x); 
      } 
      else { 
       reset();     // first delete the old content 
       object = new T(x); 
      } 
      table = x_table;  // update table pointer 
     } 
     return *this; 
    } 
+0

單挑,有一些相關的討論與這個聊天室中的有用鏈接:http://chat.stackoverflow.com/rooms/78630/discussion-between-james-adkison-and-sehe – sehe

+0

我有鏈接的回答者問題糾正他的錯誤/含糊不清。現在有道理? – Yakk

+0

是的,我認爲現在已經很清楚了,謝謝:) – Mango

回答

1

在鏈接的回答,UB是base* ptr使用,同時它還是放置新後,指向該存儲被稱爲並在那裏創建了不同類型的不同對象(它用於調用delete)。在Boost Any中情況並非如此。重新使用存儲本身不是UB。

+0

正如我已經展示了新的代碼示例,boost在底層* ptr的示例中實際上與我一樣(好吧,它們使用void *),所以shouldn那會導致同樣的問題? – Mango

+0

@Mango你調用了'delete ptr',它是UB,因爲它調用'der1'類型的對象上'base'的析構函數。 'void *'指針不調用析構函數,Boost在刪除存儲之前調用適當類型的析構函數。 – StenSoft