2011-08-07 38 views
9

爲什麼在下面的代碼示例中分配緩衝區時將char *轉換爲char **,而 這裏發生了什麼?鑄造C++問題

first_ = *reinterpret_cast<char **>(first_); 

     //CODE SAMPLE 
    public:  
     char * Allocate() 
     { 
      if (!first_) 
       return 0; 
      char *result = first_; 
      first_ = *reinterpret_cast<char **>(first_); // WHY? 
      --available_; 
      return result; 
     } 




    private: 
     char *buffers_; 
     char *first_; 
     std::size_t available_; 
     std::size_t maxnum_; 
     std::size_t buffersize_; 

    //WHOLE CLASS IS HERE 

    class Chunk 
    { 
    public: 
     Chunk(std::size_t buffersize, std::size_t buffernum) 
      : buffers_(0), 
       first_(0), 
       available_(0), 
       maxnum_(0), 
       buffersize_(0) 
     { 
      assert(buffersize > sizeof(char *) && buffernum > 0); 
      std::size_t len = buffersize * buffernum; 
      buffers_ = new char[len]; 
      first_ = buffers_; 
      available_ = buffernum; 
      maxnum_ = buffernum; 
      buffersize_ = buffersize; 

      char *begin = buffers_; 
      char *end = buffers_ + len - buffersize_; 
      *reinterpret_cast<char **>(end) = 0; 
      for (; begin < end; begin += buffersize_) 
      { 
       char **next = reinterpret_cast<char **>(begin); 
       *next = begin + buffersize_; 
      } 
     } 

     ~Chunk() 
     { 
      delete [] buffers_; 
     } 

     char * Allocate() 
     { 
      if (!first_) 
       return 0; 
      char *result = first_; 
      first_ = *reinterpret_cast<char **>(first_); 
      --available_; 
      return result; 
     } 

     void Deallocate(char *buffer) 
     { 
      *reinterpret_cast<char **>(buffer) = first_; 
      first_ = buffer; 
      ++available_; 
     } 

     bool IsFull() const 
     { 
      return available_ == 0; 
     } 

     // the buffer is one of this chunk 
     bool IsChunkBuffer(char *buffer) const 
     { 
      assert(buffer); 
      return buffer >= buffers_ && buffer < buffers_ + maxnum_ * buffersize_; 
     } 

    private: 
     char *buffers_; 
     char *first_; 
     std::size_t available_; 
     std::size_t maxnum_; 
     std::size_t buffersize_; 
    }; 
+1

此代碼對我沒有意義(直到您發佈更多代碼)。你從哪裏得到它的? – Nawaz

+0

你能顯示first_真的被分配的部分嗎?從顯示的代碼看來,它似乎毫無用處(除非first_隱藏某些列表,其中ptr到下一個存儲在first_的前4個字符中) –

回答

11

它是一個池分配器。在每個空閒塊的開始處,有一個指向下一個空閒塊的指針。當執行上面的代碼時,first_指向一個空閒塊,它是空閒塊單鏈表中的第一個。然後它將first_設置爲下一個空閒塊並返回前一個,因爲它不再位於空閒塊的列表中,所以它將被分配。

+0

+1,爲某些上下文添加Wikipedia鏈接(減少分配小塊的內存開銷,減少頻繁分配和釋放的內存碎片)。此外,Scott Meyers在「Effective C++」中有一個很好的內存池示例http://en.wikipedia.org/wiki/Memory_pool – orip

0

爲了補充@ybungalobill答案...

在C和C++ char有兩個含義:無論是作爲一個真正的char或作爲 「字節」。我自己更喜歡使用unsigned char作爲一個字節,並且通常將其定義爲清晰可辨的內容,但它仍然是您應該瞭解的內容。

因此,您在這裏看到的是對原始內存的處理(典型情況下是分配程序),它以char的數組形式出現在buffers_ = new char[len]; 中。

作者然後將該數組的大塊和使用reinterpret_cast向編譯器指示他想要在內存中的這個位置存儲什麼。

這顯然是低級別的干預(類型不安全),而不是每天都想要混淆的東西。