【发布时间】:2016-12-20 17:09:01
【问题描述】:
我问这个的原因是我需要将std::function存储在一个向量中,而我们公司内部的向量基本上是在做realloc,如果它需要更多的内存。 (基本上只是memcpy,不涉及复制/移动运算符)
这意味着我们可以放入容器中的所有元素都必须是可简单复制的。
这里有一些代码来演示我有问题的副本:
void* func1Buffer = malloc(sizeof(std::function<void(int)>));
std::function<void(int)>* func1p = new (func1Buffer) std::function<void(int)>();
std::function<void(int)>* func2p = nullptr;
*func1p = [](int) {};
char func2Buffer[sizeof(*func1p)];
memcpy(&func2Buffer, func1p, sizeof(*func1p));
func2p = (std::function<void(int)>*)(func2Buffer);
// func2p is still valid here
(*func2p)(10);
free(func1Buffer);
// func2p is now invalid, even without std::function<void(int)> desctructor get triggered
(*func2p)(10);
我知道我们应该支持元素的复制/移动,以便安全地存储 std::function。
但是我还是很好奇上面无效的std::function复制的直接原因是什么。
------------------------------------------ --------UpdateLine----------------------------- ------------
更新了代码示例。
通过更多调试我们的内部向量,我找到了此失败的直接原因。
简单复制的std::function对原始对象内存有一定的依赖关系,删除原始内存会破坏复制不好的std::function,即使没有破坏原始对象。
感谢大家对本帖的回复。这都是有价值的输入。 :)
【问题讨论】:
-
为什么我们不能简单地复制 std::function?因为标准是这样定义的。
-
只要您使用非捕获 lambda,您就可以在向量中存储函数指针。
-
这里有一些更新,我在本地犯了一些错误,我在问题中给出的代码示例实际上是有效的。
-
实际上,这是因为函数对象包含指向自身其他部分的内部指针。 Memcpying 对象会使这些指针悬空。
-
@RaymondChen,是的,这个是有效的。在破坏 func1 之后使用 func2p 很容易崩溃。
标签: c++ c++11 std-function