[英]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.