- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为泛型类型动态分配内存,并希望将泛型类型包装在 Arc 中。但是,我遇到了段错误。
当我包装 T
时,代码工作正常在Box
,这意味着从语义上讲,代码没有问题。
此外,当我使用 Vec::with_capacity()
时,代码工作正常,而不是使用 alloc()
动态分配内存.
struct Entry<T>
where
T: Sized + Clone + Default,
{
val: T,
}
struct Entries<'a, T>
where
T: Sized + Clone + Default,
{
vec: &'a [Cell<Entry<T>>],
index: usize,
}
impl<'a, T> Entries<'a, T>
where
T: Sized + Clone + Default,
{
fn new<'b>() -> Entries<'b, T> {
let bytes = 64;
let mem = unsafe {
alloc(Layout::from_size_align(bytes, align_of::<Cell<Entry<T>>>()).expect("Error"))
};
let num = bytes / size_of::<Cell<Entry<T>>>();
let raw = unsafe { from_raw_parts_mut(mem as *mut Cell<Entry<T>>, num) };
Entries { vec: raw, index: 0 }
}
fn append(&mut self, val: &T) {
self.vec[self.index].set(Entry { val: val.clone() }); // Error here
self.index += 1;
println!("Appended");
}
fn remove(&mut self) {
self.index -= 1;
println!("Removed");
}
}
fn main() {
let mut log = Entries::<Arc<u8>>::new();
let element = Arc::new(8);
log.append(&element);
println!("Reference Count for Arc {}", Arc::strong_count(&element));
log.remove();
println!("Reference Count for Arc {}", Arc::strong_count(&element));
}
问题
Box
工作和Arc
不适用于动态分配的内存?Arc
使用 Vec::with_capacity()
完成分配后工作但不是在alloc()
时使用过吗?Playground 链接
Arc using alloc
(第一种情况请将Arc改为Box)。
最佳答案
这行不健全:
let raw = unsafe { from_raw_parts_mut(mem as *mut Cell<Entry<T>>, num) };
创建对 num
元素切片的引用是不正确的,因为已初始化 0 个元素。当 T
是 Arc<u8>
(指针类型)时,这意味着它们可以指向任意数据,或者为空。如果您只创建了切片引用并且从未取消引用它,它可能会起作用,但是这一行:
self.vec[self.index].set(Entry { val: val.clone() });
将尝试删除 Arc
中已有的 Cell
,然后将其替换为新的 Arc
。删除 Arc
会释放指针,因为它未初始化,因此会导致未定义的行为。
Why is
Box
working andArc
not working for dynamically allocated memory?
基本上是偶然的。 Drop
的 Box
只是将指针传递给 free
,但 Drop
的 Arc
必须遵循它才能检查引用计数。如果内存最初被清零,使用典型的分配器,Box
可能看起来可以工作,而 Arc
会出现段错误。但是,您不能依赖这种行为,这引出了我的下一点:
The code is working fine when I wrap the
T
inBox
, which means that semantically there is no issue with the code.
这不是真的。因为代码看起来可以正常工作并不意味着它没有错误!甚至 Box
版本也不正确。避免内存安全错误的最佳方法是不使用 unsafe
。当您使用 unsafe
时,您必须小心维护安全代码所依赖的所有不变量,例如(在本例中)“引用必须始终有效”。
Why is
Arc
working when the allocation is done usingVec::with_capacity()
but not whenalloc()
is used?
Vec::with_capacity
创建一个空 Vec
。当您在此空 Vec::push
上调用 Vec
时,它不会在索引 0 处的未初始化元素上调用 drop
;它只是初始化它(并将长度增加到 1)。
这是一个很好的例子,说明了为什么正确使用 unsafe
比看起来更棘手,以及为什么大多数 Rust 程序员更喜欢使用经过彻底测试和审查的数据结构,例如 Vec
,而不是使用 unsafe
自己创建。
( Entries
至少还有一个问题,那就是它引用的数据可能永远不会被正确释放;因为 new
创建一个具有任意生命周期的 Entries
,您可以使用它来获取对内部 block 的引用,该内部 block 的生命周期比Entries
对象本身。alloc
创建的数据无法被释放,因此是无主的。解决这个问题归结为使用更多的 unsafe
,并在 Vec
中重新创建大部分 Entries
——但是为什么要麻烦呢,因为 Vec
已经存在了?)
关于templates - 在 Arc 中包装泛型类型的堆分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59572550/
template struct List { }; template class> struct ListHelper; template struct ListHelper> { };
最近,我注意到 html/template.Template 的 Templates() 与 text/template.Template 的工作方式不同。 // go1.12 func main()
我正在尝试使用 polymer 1.0 实现一个网站。我有一个自定义元素 my-greeting,里面有一些模板重复。 我想做的是获取一个名为 TARGET 的字符串,但我不知道该怎么做: /cons
(是的,由于我糟糕的英语,标题很奇怪;我希望有人能改进它。) 接听this question ,我发现这段代码有效: template class A { }; template class U>
这个问题在这里已经有了答案: How to import and use different packages of the same name (2 个答案) 关闭 4 年前。 我正在使用 Go
我的想法是这是不可能的,或者我缺少一个额外的步骤。无论哪种方式,我都被卡住了,无法弄清楚。 使用内联模板的原因是能够使用 Laravel Blade 语法并结合 Vue Js 的强大功能。似乎是两者中
我已经尝试实现一个“模板模板模板”——模板类来满足我的需求(我对使用模板元编程很陌生)。不幸的是,我发现以下主题为时已晚: Template Template Parameters 不过,我需要实现如
Helm _helpers.tpl? Helm 允许使用 Go templating在 Kubernetes 的资源文件中。 一个名为 _helpers.tpl 的文件通常用于定义 Go 模板助手,语
{{template "base"}} 和 {{template "base".}} 有什么区别? 我用的是go-gin,两者都可以正常运行。我在文档中找不到关于此的任何描述。 最佳答案 来自 god
我有一个本质上充当查找表的函数: function lookup(a::Int64, x::Float64, y::Float64) if a == 1 z = 2*x + y else if a =
当 out 成员函数(来自模板和特化)都需要模板时,为什么 c++ 需要模板参数,因为我没有得到它,谷歌也没有帮助。必须是c++11但和c++1z有同样的错误。 我正在使用 g++ 7.3.0 收到此
我正在寻找简单的方法来将带有 ${myvar} 的简单模板转换为带有 {{ myvar }} 的 GO 模板。 是否有任何库可以实现这一点? 最佳答案 使用正则表达式查找 \${([a-z0-9\_\
我有这个模板可以将 slice 的多个项目解析到页面上。它确实做得很好。 但是,我现在想使用完全相同的模板来根据范围索引解析 slice 的单个值。该 slice 在多个文件中使用,所以我不能像 Sl
要清理模板文件夹,我想将常用模板保存在子文件夹中。目前我有以下文件结构: main.go templates/index.tpl # Main template for the
最近我设计了元类型和允许编译时类型连接的可能操作: #include template typename T> struct MetaTypeTag {}; /*variable template
准备模板时发生错误。谁能告诉你怎么修? 如有必要,还可以编辑变量。 vars: AllСountry: - "name1" - "name2"
我在使用新的匿名模板引擎时遇到问题。它不能使用嵌套模板。我收到错误消息:“此模板引擎不支持嵌套在其模板中的匿名模板”。 我的问题:我如何强制 knockout JS 使用jquery 模板引擎,而不是
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我在 C++ 中使用带有模板的集合: template class OMSSVDisk : public OMSSObjProperties{ set memberPDs; }; 如上面代码中
因为我喜欢分离接口(interface)和实现,而不是只在头文件中实现模板类,我将它分成 .h 和 .tpp(.tpp 这样它就不会用 *.cpp 编译)。然后我将 tpp 包含在头文件的末尾,就在
我是一名优秀的程序员,十分优秀!