[英]How to understand freelist implementation for linked-list in C++?
I don't understand the last few lines here.我不明白这里的最后几行。
// 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;
In particular, why do we need to define a pointer to a pointer in the last line?特别是,为什么我们需要在最后一行定义一个指向指针的指针?
Link<Elem>::freelist
is already a pointer, so why do we need to set another pointer to that pointer to NULL
? Link<Elem>::freelist
已经是一个指针,那么为什么我们需要将另一个指向该指针的指针设置为NULL
呢?
Can someone clear this up for me?有人可以帮我解决这个问题吗? I'm very confused.
我很困惑。
Distilling your example down, this is what you have:提炼你的例子,这就是你所拥有的:
class Link {
static Link* freelist;
}
Link* Link::freelist = NULL;
As the comment mentions, "The freelist head pointer is actually created here".正如评论中提到的,“freelist 头指针实际上是在这里创建的”。 The first part is a declaration of the static variable
freelist
but it does not actually define it.第一部分是静态变量
freelist
的声明,但实际上并没有定义它。 The definition below mimics the declaration (and gives it a value).下面的定义模仿声明(并给它一个值)。 It does not add another level of pointer.
它不会添加另一个级别的指针。
Not only the last two lines should raise questions, but the implementation of the operator new
.不仅最后两行应该引起问题,而且
operator new
的实现。
Let's consider the following code:让我们考虑以下代码:
struct S {
// ...
};
auto list = new List<S>;
Here new List<S>
will call List<S>::operator new
to allocate raw memory.这里
new List<S>
将调用List<S>::operator new
来分配原始内存。 It will call global ::new
, and that global ::new
will allocate memory (with ::operator new
) and construct Link
, ie S
and Link*
, in it.它将调用 global
::new
,并且 global ::new
将分配内存(使用::operator new
)并在其中构造Link
,即S
和Link*
。 Then our local new
will construct Link
again at the same memory location.然后我们的本地
new
将在相同的内存位置再次构造Link
。 As a result, S
will be constructed twice at the same memory location.因此,
S
将在同一内存位置构造两次。 Depending on S
, this can lead to undefined behaviour and/or memory leaks.根据
S
,这可能导致未定义的行为和/或内存泄漏。
Simple example:简单的例子:
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;
}
Sample output:示例输出:
ctor at 0x24b8e80
ctor at 0x24b8e80
dtor at 0x24b8e80
Declaration of static non-const member of class requires exactly one out-of-line definition.类的静态非常量成员的声明只需要一个外部定义。 Static members do not use their class object's storage, so you have to declare and initialize its own separately.
静态成员不使用它们的类对象的存储,所以你必须单独声明和初始化它自己的。
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 is actually a "global" variable which could be accessed though context of class Link, eg Link::freelist
if it was public. freelist 实际上是一个“全局”变量,它可以通过类 Link 的上下文访问,例如
Link::freelist
如果它是公共的。 In this particular case , it's just being shared between all instances of class object.在这种特殊情况下,它只是在类对象的所有实例之间共享。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.