[英]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
,即S
和Link*
。 然后我們的本地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.