我在执行此代码时遇到了段错误。特别是在调用g_lru_stack.add_node(& lru_node)之后。
在GDB下运行表明虚拟节点看起来不像是已经初始化了。这与extern全局变量的初始化有关吗?如果有的话,我们将非常感谢您的帮助。
我已经在header和cpp文件中包含了片段。
具体来说,我的问题是: 如何获取在object.cc顶部声明的LRU_Stack g_lru_stack来调用不带参数的LRU_Node ctor。
似乎这个ctor永远不会被调用,因此为什么我的虚节点没有被初始化。
class obj_payload;
extern cas_mutex g_lru_stack_mutex;
class LRU_Node {
private:
obj_payload* payload;
LRU_Node* up;
LRU_Node* down;
size_t predicted_bytes_in_cache;
public:
LRU_Node() : payload(nullptr), up(this), down(this), predicted_bytes_in_cache(1337) {} // Dummy ctor
LRU_Node(obj_payload* p) : payload(p), up(nullptr), down(nullptr), predicted_bytes_in_cache(88) {} // Normal Creation of node
//Adds a node to the top of the stack
//Has dummy context
void add_to_stack(LRU_Node* newNode);
//Sets how many bytes of the object are predicted to be in the cache
//Has dummy context
void is_node_in_cache(LRU_Node* node);
//Moves a node to the top of the stack
//Has dummy context
void move_node_to_top(LRU_Node* node);
//Has context of caller
size_t get_predicted_bytes_in_cache();
};
class LRU_Stack {
LRU_Node dummy;
public:
void add_node(LRU_Node* node);
void move_node_to_top(LRU_Node* node);
};
extern LRU_Stack g_lru_stack;
class obj_payload {
typedef uint32_t ctr_t;
private:
ctr_t refcnt;
const uint32_t sz; // size of the data space in bytes
LRU_Node lru_node; // Jordan -- This arg objects node for the LRU_Stack
obj_payload( typeinfo tinfo_,
uint32_t size_,
int refcnt_init=1 )
: refcnt( refcnt_init ),
sz( size_ ),
tinfo( tinfo_ ), lru_node(this) {
g_lru_stack.add_node(&lru_node);
}
#include "object.h"
namespace obj {
//Jordan -- Global LRU_Node Stack
cas_mutex g_lru_stack_mutex;
LRU_Stack g_lru_stack;
//Adds a node to the top of the stack
//Has dummy context
void LRU_Node::add_to_stack(LRU_Node* newNode) {
newNode->down = down; // Set the new nodes previous -> dummys previous
newNode->up = this; // Set new nodes next -> dummy
down->up = newNode; // Dummy next -> new node (i.e. Previous top of stack node up -> newNode)
down = newNode; // Dummy previous -> new node (i.e. Dummy down pointer now links back round to the new node at the top)
}
//Sets how many bytes of the object are predicted to be in the cache
//Has dummy context
void LRU_Node::is_node_in_cache(LRU_Node* node) {
size_t total = 0;
LRU_Node* orignal = node;
while (node != this) {
total += node->payload->get_size(); // Add current size to total
node = node->up; // Go to next node
}
node = orignal; //Reset node to the passed in node, then set how many bytes it has contained within cache
if (total <= cache_size) {
node->predicted_bytes_in_cache = node->payload->get_size();
}
else {
node->predicted_bytes_in_cache = (node->payload->get_size()) - (total - cache_size) < node->payload->get_size() ? (node->payload->get_size()) - (total - cache_size) : 0;
}
}
//Moves a node to the top of the stack
//Has dummy context
void LRU_Node::move_node_to_top(LRU_Node* node) {
if (down != node) { // Check that the node to move is not already top of stack
node->down->up = node->up;
node->up->down = node->down;
if (down == node->up) { // If the node is seccond top of stack
node->up->up = node;
}
node->down = down;
node->up = this;
down->up = node;
down = node;
}
}
//Has context of caller
size_t LRU_Node::get_predicted_bytes_in_cache() {
return predicted_bytes_in_cache;
}
//Has dummy context
bool LRU_Node::is_empty() {
return (up == this);
}
void LRU_Stack::add_node(LRU_Node* node) {
g_lru_stack_mutex.lock();
dummy.add_to_stack(node);
g_lru_stack_mutex.unlock();
}
void LRU_Stack::move_node_to_top(LRU_Node* node) {
g_lru_stack_mutex.lock();
dummy.is_node_in_cache(node);
dummy.move_node_to_top(node);
g_lru_stack_mutex.unlock();
}
答案 0 :(得分:2)
&#34; extern globals&#34;不是对象(除非它们包含初始值设定项):它们是前向声明。
全局对象分两个阶段初始化:
好像UB让你在那里。
要解决错误,请执行以下操作之一:
将对象作为静态放入访问器函数中。 Init将首次使用(线程安全!)。
Type& getTypeSingleton() {
static Type x/*optional initializer*/;
return x;
}