从模板化队列中检索时的核心转储
Core Dump When Retrieving From Templated Queue
背景
我想要一个 class MyClass
来存储不同类型的队列。为此,我创建了一个接口 ValueInterface
和一个派生 class Value<T>
。我现在可以使用 queue<ValueInterface>
成员变量将此派生 class 的实例存储在 MyClass
中。
注意: 为了我自己的目的,我有意保持 MyClass
非模板化,我想要依赖模板函数。
目标
我有下面的代码可以编译,但是下面的测试代码中的 运行 导致核心转储。我认为我在使用 std::unique_ptr
时很小心,并确保尽可能使用 std::move
。 GetValueAndAdvance<T>
函数导致错误。当我尝试从模板化队列中检索时出了点问题。我知道它很乱,我假设 static_cast
可以工作,但是 我怎样才能从存储 std::queue
的 std::queue
中检索 Value<T>
14=] ?
我不知道问题是否出在 StoreValue
或 GetValueAndAdvance
上,或者整个设计是否存在缺陷并且在类型敏感语言中是不可能的。
测试中的用法:
这是我想要完成的功能。这是假设每个 MyClass
一次只用于一种类型。因此,让我们假设没有人会在同一个 MyClass
对象上调用 StoreValue<int>(4)
和 StoreValue<string>("hello")
。但出于我自己的原因,我想保持 MyClass
非模板化。
MyClass my_class;
my_class.StoreValue<int>(5);
int val;
my_class.GetValueAndAdvance<int>(&val);
std::cout << "value: " << val; // Should print "value: 5"
代码:
class ValueInterface {};
template <class T>
class Value : public ValueInterface {
public:
Value(T val) : value_(val){};
T get() { return value_; }
private:
const T& value_;
};
class MyClass {
public:
template <class T>
void GetValueAndAdvance(T* out_val) {
if (!queued_values_.empty()) {
auto unique_value = std::move(queued_values_.front());
queued_values_.pop();
auto unique_value_typed = static_cast<Value<T>*>(unique_value.get());
*out_val = unique_value_typed->get();
// Prints 0 even though it should return 5 based on the test code (below)
std::cout << "value: " << unique_value_typed->get();
}
return;
}
template <class T>
MyClass* StoreValue(const T& value) {
auto wrapped_value = std::make_unique<Value<T>>(value);
queued_values_.push(std::move(wrapped_value));
return this;
}
private:
std::queue<std::unique_ptr<ValueInterface>> queued_values_;
};
错误消息片段
F0418 18:08:57.928949 244111 debugallocation.cc:763] RAW: delete size mismatch: passed size 1 != true size 4
@ 0x7fda024f8a1f (anonymous namespace)::RawLogVA()
@ 0x7fda024f8525 base_raw_logging::RawLog()
@ 0x42b162 tc_delete_sized
@ 0x40c595 std::default_delete<>::operator()()
@ 0x40c503 std::unique_ptr<>::~unique_ptr()
@ 0x40b552 mynamespace::MyClass::GetValueAndAdvance<>()
问题出在 Value
class 中,其中 value_
被定义为 对常量值 的引用
const T& value_;
将 value_
定义为正常(非参考)值
const T value_;
你应该从 std::cout
.
得到 5
观察Value<T>
的构造函数
Value(T val) : value_(val){};
value_
引用被初始化为一个 临时 变量 (val
),该变量在构造函数结束时超出范围.
因此 value_
绑定到可以重复使用的内存,因此具有未定义的值。
背景
我想要一个 class MyClass
来存储不同类型的队列。为此,我创建了一个接口 ValueInterface
和一个派生 class Value<T>
。我现在可以使用 queue<ValueInterface>
成员变量将此派生 class 的实例存储在 MyClass
中。
注意: 为了我自己的目的,我有意保持 MyClass
非模板化,我想要依赖模板函数。
目标
我有下面的代码可以编译,但是下面的测试代码中的 运行 导致核心转储。我认为我在使用 std::unique_ptr
时很小心,并确保尽可能使用 std::move
。 GetValueAndAdvance<T>
函数导致错误。当我尝试从模板化队列中检索时出了点问题。我知道它很乱,我假设 static_cast
可以工作,但是 我怎样才能从存储 std::queue
的 std::queue
中检索 Value<T>
14=] ?
我不知道问题是否出在 StoreValue
或 GetValueAndAdvance
上,或者整个设计是否存在缺陷并且在类型敏感语言中是不可能的。
测试中的用法:
这是我想要完成的功能。这是假设每个 MyClass
一次只用于一种类型。因此,让我们假设没有人会在同一个 MyClass
对象上调用 StoreValue<int>(4)
和 StoreValue<string>("hello")
。但出于我自己的原因,我想保持 MyClass
非模板化。
MyClass my_class;
my_class.StoreValue<int>(5);
int val;
my_class.GetValueAndAdvance<int>(&val);
std::cout << "value: " << val; // Should print "value: 5"
代码:
class ValueInterface {};
template <class T>
class Value : public ValueInterface {
public:
Value(T val) : value_(val){};
T get() { return value_; }
private:
const T& value_;
};
class MyClass {
public:
template <class T>
void GetValueAndAdvance(T* out_val) {
if (!queued_values_.empty()) {
auto unique_value = std::move(queued_values_.front());
queued_values_.pop();
auto unique_value_typed = static_cast<Value<T>*>(unique_value.get());
*out_val = unique_value_typed->get();
// Prints 0 even though it should return 5 based on the test code (below)
std::cout << "value: " << unique_value_typed->get();
}
return;
}
template <class T>
MyClass* StoreValue(const T& value) {
auto wrapped_value = std::make_unique<Value<T>>(value);
queued_values_.push(std::move(wrapped_value));
return this;
}
private:
std::queue<std::unique_ptr<ValueInterface>> queued_values_;
};
错误消息片段
F0418 18:08:57.928949 244111 debugallocation.cc:763] RAW: delete size mismatch: passed size 1 != true size 4
@ 0x7fda024f8a1f (anonymous namespace)::RawLogVA()
@ 0x7fda024f8525 base_raw_logging::RawLog()
@ 0x42b162 tc_delete_sized
@ 0x40c595 std::default_delete<>::operator()()
@ 0x40c503 std::unique_ptr<>::~unique_ptr()
@ 0x40b552 mynamespace::MyClass::GetValueAndAdvance<>()
问题出在 Value
class 中,其中 value_
被定义为 对常量值 的引用
const T& value_;
将 value_
定义为正常(非参考)值
const T value_;
你应该从 std::cout
.
5
观察Value<T>
Value(T val) : value_(val){};
value_
引用被初始化为一个 临时 变量 (val
),该变量在构造函数结束时超出范围.
因此 value_
绑定到可以重复使用的内存,因此具有未定义的值。