问题标签 [memory-safety]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
rust - 为什么 &mut self 允许借用 struct 成员,但不允许将 self 借用到不可变方法?
如果我有一个封装两个成员的结构,并基于另一个更新一个,那么只要我这样做就可以了:
也就是说,当我直接引用self.b
. 但是当我改变do_stuff()
这个:
编译器抱怨:cannot borrow `*self` as immutable because `self.a` is also borrowed as mutable
.
如果我需要做一些比返回成员更复杂的事情来获取参数a.do_something()
怎么办?我必须创建一个b
按值返回的函数并将其存储在绑定中,然后将该绑定传递给do_something()
?如果b
复杂怎么办?
根据我的理解,更重要的是,编译器从这里救了我什么样的内存不安全?
rust - 为什么 Rust 文档说共享对向量的引用会创建一个无效向量,即使该向量在堆上?
以下是The Rust Programming Language 关于所有权一章的摘录:
现在考虑以下代码片段:
第一行
v
像上面一样为堆栈上的向量对象分配内存x
。但除此之外,它还在堆上为实际数据分配一些内存([1, 2, 3]
)。Rust 将此堆分配的地址复制到一个内部指针,该指针是放置在堆栈上的向量对象的一部分(我们称之为数据指针)。值得指出(即使冒着说明显而易见的风险)向量对象及其数据存在于单独的内存区域中,而不是单个连续的内存分配(由于我们目前不会讨论的原因) . 向量的这两个部分(堆栈上的一个和堆上的一个)在长度、容量等方面必须始终相互一致。
当我们转到
v
时v2
,Rust 实际上将向量对象按位复制v
到由 表示的堆栈分配中v2
。这个浅拷贝不会创建包含实际数据的堆分配的副本。这意味着将有两个指向向量内容的指针,它们都指向堆上的相同内存分配。如果一个人可以同时访问两者v
,就会通过引入数据竞争来违反 Rust 的安全保证v2
。例如,如果我们通过以下方式将向量截断为两个元素
v2
:并且
v
仍然可以访问,我们最终会得到一个无效的向量,因为v
不知道堆数据已被截断。现在,v
堆栈上的向量部分与堆上的相应部分不一致。v
仍然认为向量中有三个元素,并且很乐意让我们访问不存在的元素v[2]
,但是您可能已经知道这是灾难的根源。特别是因为它可能导致分段错误或更糟的是允许未经授权的用户从他们无权访问的内存中读取。
使用 截断向量后v2
,将在堆内存上更新截断的值。v1
仍然看到堆内存,截断后,它看到了新值。那为什么书上说
并且
v
仍然可以访问,我们最终会得到一个无效的向量,因为v
不知道堆数据已被截断
dynamic - Rust 中的所有权跟踪:Box 之间的区别(堆)和 T(栈)
使用编程语言 Rust 进行实验,我发现编译器能够非常准确地跟踪堆栈上某个结构的字段的移动(它确切地知道移动了哪个字段)。但是,当我将结构的一部分放入 a Box
(即,将其放入堆中)时,编译器不再能够确定在取消引用框后发生的所有事情的字段级移动。它将假设“盒子内”的整个结构已经移动。让我们首先看一个所有内容都在堆栈中的示例:
现在是相同的示例,但有一个细微的变化:我们将InnerContainer
放入一个盒子 ( Box<InnerContainer>
)。
我怀疑它与堆栈的性质与堆的性质有关,前者是静态的(至少每个堆栈帧),而后者是动态的。也许编译器需要安全地发挥它,因为某种原因我不能很好地表达/识别。
python - Python 类型安全吗?
根据维基百科
如果计算机科学家不允许违反类型系统规则的操作或转换,则认为该语言是“类型安全的”。
由于 Python 运行时检查确保满足类型系统规则,我们应该将 Python 视为一种类型安全的语言。
Jason Orendorff 和 Jim Blandy 在Programming Rust中提出了同样的观点:
请注意,类型安全与语言是在编译时检查类型还是在运行时检查类型无关:C 在编译时检查,并且不是类型安全的;Python 在运行时检查,并且是类型安全的。
静态类型检查和类型安全的概念都是分开的。
那是对的吗?
swift - swift中的内存安全(输入参数/长期访问)
我正在快速阅读内存安全章节,并想尝试这个例子:
如果它说由于对stepsize
变量的访问冲突(长期书面访问)而导致错误,它实际上会编译并给我正确的答案(即2)。
谁能举例说明长期访问变量何时会导致错误?我不能带一个。
编辑:
我在 Xcode 9.2 上的操场上进行了测试
c++ - C++,static_cast 到 void* 并跨进程返回是否安全?
我在 Linux 系统上同时运行了两个相同的二进制文件(不同的命令行参数,所以它们在做不同的事情)。在一个进程中,我将一个对象 memcopy 到某个共享内存区域;在另一个过程中,我检索具有正确大小的对象,并将指向它的指针作为 a void*
,并将static_cast
它指向原始类型的指针。
这被认为是安全的吗?对象不一定是 POD。
swift - Swift 中“+=”运算符的内存安全
我一直在快速学习,遇到了一个关于内存安全的问题。+=
运算符在左侧接受一个参数,该inout
参数应该对整个函数调用具有写访问权限。left = right+left
它在其实现中做了类似的事情。它似乎是写入和读取访问的重叠。这怎么不违反内存安全?
编辑:根据The Swift Programming Language,它可以在一个线程中发生:
但是,这里讨论的冲突访问可能发生在单个线程上,不涉及并发或多线程代码。
详细说明:这里有两个来自The Swift Programming Language (Swift 4.1 beta) 的例子。我很困惑+=
结构中的这种自定义实现如何Vector2D
正常:
当这不是:
进一步编辑:
我认为我的问题确实是 += 作为一个函数,特别是在使用时
或使用自定义实现:
这没有任何错误。但是 func 从左侧获取一个 inout,因此对“step”具有长期写入访问权限,那么如果右侧也传入“step”,我很困惑这不是“step”的即时读取访问”与“步”的长期书写重叠。或者,当您为两个 inout 参数传入同一个实例时,这只是一个问题,而不是一个 inout 和一个常规参数?
c++ - 是否有将引用返回到临时的 C++ 警告?
这种情况有一个错误:
乃至
但不是这个:
并且(不那么令人惊讶)不是这个:
特别是在这种std::vector
情况下,我知道这个警告会非常棘手,因为对于编译器来说,const int&
返回的std::vector<int>::operator[](size_t) const
不是对临时的引用。不过,我实际上对std::array
没有失败感到有点惊讶,因为这种类似的情况确实给了我一个错误:
是否有任何流行的编译器有可以捕获这些情况的警告/错误?我可以想象一个保守的版本,它会警告返回来自临时成员函数调用的引用。
我用类似下面的方法绊倒了这个问题,在其中我内联了一系列链接的调用,但是因为 C++ 允许您将 locals 分配给const&
,所以详细版本可以工作,而表面上相同的版本会立即删除临时,留下一个悬空引用:
那输出
swift - 与 UnsafeMutablePointer 一起使用时,Swift 中的局部变量是否隐式初始化为 nil?
VTCreateCGImageFromCVPixelBuffer () 接收一个 UnsafeMutalePointer。假设发生错误并且它没有分配给 cgImage。我有可能返回一个未初始化的变量吗?如果是这样,我需要用 nil 初始化变量:
这不是欺骗Do Optionals 默认为 nil 吗?因为这个问题谈到了 UnsafeMutablePointers,并且涉及局部变量,而该问题谈到了属性。
swift - 为什么一个函数对其所有输入输出参数都有长期写入权限?
根据 Swift Programming Language Guide (for Swift 4.2) 中的“内存安全”一章,有一句话“A function has long-term write access to all its in-out parameters”。 https://docs.swift.org/swift-book/LanguageGuide/MemorySafety.html
我创建了一个新的命令行工具项目来在 Xcode 10.1 中验证它。
我希望输出为 1,但实际输出是崩溃日志“同时访问 0x100587430,但修改需要独占访问”。
我知道这是关于访问输入输出参数的冲突,但我不知道为什么会这样。为什么一个函数对其所有输入输出参数都有长期写入权限?