簡體   English   中英

如何理解C++中鏈表的freelist實現?

[英]How to understand freelist implementation for linked-list in C++?

我不明白這里的最后幾行。

// Singly linked list node with freelist support
template<typename Elem> class Link {
private:
  static Link<Elem>* freelist; // Reference to freelist head
public:
  Elem element;                // Value for this node
  Link* next;                  // Point to next node in list

  // Constructors
  Link(const Elem& elemval, Link* nextval = NULL)
    { element = elemval; next = nextval; }
  Link(Link* nextval = NULL) { next = nextval; }

  void* operator new(size_t) { // Overloaded new operator
    if (freelist == NULL) return ::new Link; // Create space
    Link<Elem>* temp = freelist; // Can take from freelist
    freelist = freelist->next;
    return temp;                 // Return the link
  }

  // Overloaded delete operator
  void operator delete(void* ptr) {
    ((Link<Elem>*)ptr)->next = freelist; // Put on freelist
    freelist = (Link<Elem>*)ptr;
  }
};

// The freelist head pointer is actually created here
template<typename Elem>
Link<Elem>* Link<Elem>::freelist = NULL;

特別是,為什么我們需要在最后一行定義一個指向指針的指針? Link<Elem>::freelist已經是一個指針,那么為什么我們需要將另一個指向該指針的指針設置為NULL呢?

有人可以幫我解決這個問題嗎? 我很困惑。

提煉你的例子,這就是你所擁有的:

class Link {
    static Link* freelist;
}

Link* Link::freelist = NULL;

正如評論中提到的,“freelist 頭指針實際上是在這里創建的”。 第一部分是靜態變量freelist聲明,但實際上並沒有定義它。 下面的定義模仿聲明(並給它一個值)。 它不會添加另一個級別的指針。

不僅最后兩行應該引起問題,而且operator new的實現。

讓我們考慮以下代碼:

struct S { 
    // ... 
};

auto list = new List<S>;

這里new List<S>將調用List<S>::operator new來分配原始內存。 它將調用 global ::new ,並且 global ::new將分配內存(使用::operator new )並在其中構造Link ,即SLink* 然后我們的本地new將在相同的內存位置再次構造Link 因此, S將在同一內存位置構造兩次。 根據S ,這可能導致未定義的行為和/或內存泄漏。

簡單的例子:

struct S {
    S()  { std::cout << "ctor at " << this << '\n'; }
    ~S() { std::cout << "dtor at " << this << '\n'; }
};

int main() {
    auto list = new Link<S>;
    delete list;
}

示例輸出:

ctor at 0x24b8e80
ctor at 0x24b8e80
dtor at 0x24b8e80

類的靜態非常量成員的聲明只需要一個外部定義。 靜態成員不使用它們的類對象的存儲,所以你必須單獨聲明和初始化它自己的。

class Link {
    static Link* freelist; // declaring that such object exists
};

// Shouldn't appear in a header file  to not break One Definition Rule
Link* Link::freelist = nullptr; // initialization

freelist 實際上是一個“全局”變量,它可以通過類 Link 的上下文訪問,例如Link::freelist如果它是公共的。 在這種特殊情況下,它只是在類對象的所有實例之間共享。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM