在C#或Rust中,unsafe关键字标记代码能够直接使用内存指针,绕过某些语言的安全检查。在Java中,`sun.misc.Unsafe`是一个执行低级,不安全操作的特殊类。
How to safely reinterpret Vec<f64> as Vec<num_complex::Complex<f64>> with half size?
我通过外部 C 库(最好不要更改)以 [i_0_real, i_0_imag, i_1_real, i_1_imag, ...] 的形式将复数数据填充到 Vec 中,看起来这个 Vec 我通过外部 C 库(最好不要更改)以 Vec<f64> 的形式将复数数据填充到 [i_0_real, i_0_imag, i_1_real, i_1_imag, ...] 中,看起来这个 Vec<f64> 具有与一半的 Vec<num_complex::Complex<f64>> 相同的内存布局鉴于num_complex::Complex<f64>的数据结构与[f64; 2]的内存布局兼容,如here所述,长度将是。我想这样使用它而不需要重新分配一个可能很大的缓冲区。 我假设在 from_raw_parts() 中使用 std::vec::Vec 来伪造一个新的 Vec 是有效的,它拥有旧的 Vec 的记忆(通过忘记旧的 Vec)并使用 size / 2和capacity / 2,但这需要不安全的代码。是否有一种“安全”的方式来进行这种数据重新解释? Vec 在 Rust 中分配为 Vec<f64> 并由使用 .as_mut_ptr() 填充 Vec<f64> 的 C 函数填充。 我当前的编译不安全实现: extern crate num_complex; pub fn convert_to_complex_unsafe(mut buffer: Vec<f64>) -> Vec<num_complex::Complex<f64>> { let new_vec = unsafe { Vec::from_raw_parts( buffer.as_mut_ptr() as *mut num_complex::Complex<f64>, buffer.len() / 2, buffer.capacity() / 2, ) }; std::mem::forget(buffer); return new_vec; } fn main() { println!( "Converted vector: {:?}", convert_to_complex_unsafe(vec![3.0, 4.0, 5.0, 6.0]) ); } 是否有一种“安全”的方式来进行这种数据重新解释? 没有。至少,这是因为你需要知道的信息没有在 Rust 类型系统中表达,而是通过散文(也就是文档)表达: Complex<T> 是与数组兼容的内存布局[T; 2]. — Complex 文档 如果一个 Vec 已经分配了内存,那么 [...] 它的指针指向 len 按顺序初始化的连续元素(如果你将它强制为一个切片你会看到什么), — Vec 文档 数组强制切片 ([T]) — 数组文档 由于Complex与数组内存兼容,数组的数据与切片内存兼容,而Vec的数据与切片内存兼容,这种转换应该是安全的,即使编译器不能告诉这个。 此信息应附加(通过评论)到您的不安全块。 我会对你的功能做一些小的调整: 同时有两个Vec指向相同的数据让我非常紧张。这可以通过引入一些变量并在创建另一个之前忘记一个变量来避免。 删除return关键字更地道 添加一些断言数据的起始长度是二的倍数 正如 rodrigo 指出的,容量很可能是奇数。为了避免这种情况,我们调用shrink_to_fit。这样做的缺点是 Vec may 需要重新分配和复制内存,具体取决于实现。 展开unsafe块以覆盖确保安全不变量得到维护所需的所有相关代码。 pub fn convert_to_complex(mut buffer: Vec<f64>) -> Vec<num_complex::Complex<f64>> { // This is where I'd put the rationale for why this `unsafe` block // upholds the guarantees that I must ensure. Too bad I // copy-and-pasted from Stack Overflow without reading this comment! unsafe { buffer.shrink_to_fit(); let ptr = buffer.as_mut_ptr() as *mut num_complex::Complex<f64>; let len = buffer.len(); let cap = buffer.capacity(); assert!(len % 2 == 0); assert!(cap % 2 == 0); std::mem::forget(buffer); Vec::from_raw_parts(ptr, len / 2, cap / 2) } } 为了避免所有关于容量的担忧,您可以将切片转换为Vec。这也没有任何额外的内存分配。它更简单,因为我们可以“丢失”任何奇数尾随值,因为 Vec 仍然保持它们。 pub fn convert_to_complex(buffer: &[f64]) -> &[num_complex::Complex<f64>] { // This is where I'd put the rationale for why this `unsafe` block // upholds the guarantees that I must ensure. Too bad I // copy-and-pasted from Stack Overflow without reading this comment! unsafe { let ptr = buffer.as_ptr() as *mut num_complex::Complex<f64>; let len = buffer.len(); assert!(len % 2 == 0); std::slice::from_raw_parts(ptr, len / 2) } }
移除Java 9中的sun.misc.Unsafe会破坏Spring、Hibernate。
我在这里读到,如果Oracle在Java 9中删除sun.misc.Unsafe,Spring和许多其他流行的库将会崩溃。 然而,在Spring或Hibernate中没有对这个类的静态引用。那么,是...
.NET有C#和VB*作为(相对)高级语言,它们都是编译成.NET CLI中间代码(.NET相当于Java的 "字节码"),而不是原生机器代码。有 ...
从语义学的角度来看,Rust中的"&mut "noalias的未定义行为是什么时候发生的?
正如Rust参考文献所说 打破了指针别名规则.&mut T和&T遵循LLVM的scoped noalias模型,除非&T包含一个UnsafeCell。这真是...
有没有一种安全的方法让一个结构存储一个将在结构外被修改的向量的片断?
我正在实现处理长度为k*n的向量的代码,并创建了k个长度为n的点,这些点引用了原始向量的一个片断: struct Point { values: &'a [f32], } impl&...。
考虑以下// //只是一系列相同类型#[repr(C)]#[derive(Debug)] struct S {{a:T,b:T,c:T,d: T,} impl S ]
我想将一个字节*转换为一个字节[],但我也想拥有一个可重用的功能来做到这一点:公共不安全静态T [] Create ((T * ptr,int length){T []数组=新的T [长度];为(...
您应该在C#代码中使用指针吗?有什么好处? Microsoft推荐吗?
C#Casting T,其中T:使用Unsafe类将其构造为没有装箱的接口
我需要编写一个无分配代码,当从带有结构约束的泛型参数T强制转换为访问一个实现的属性的接口时,要避免装箱。我以前解决了这个问题...
将C ++代码转换为C#。将double转换为double *的问题*
我在将C ++代码转换为C#时遇到问题。我不知道如何将double转换为double * c ++代码void Kohonen :: Initialize(){int i;双* optr; ClearWeights(); RandomizeWeights(); ...
我正在尝试执行此操作,但是似乎没有任何内容分配给BoneID或BoneWeights,在C#中执行此操作的正确方法是什么?公共不安全的结构VertexBoneData {public ...
我正在尝试执行此操作,但是似乎没有任何内容分配给BoneID或BoneWeights,在C#中执行此操作的正确方法是什么?公共不安全的结构VertexBoneData {public ...
unsafeDupablePerformIO和accursedUnutterablePerformIO有什么区别?
我在Haskell库的受限部分中徘徊,发现了这两个邪恶的咒语:{-System.IO.Unsafe-} unsafeDupablePerformIO :: IO a->一个unsafeDupablePerformIO(IO m)= case ...
[嗨,我有一个c本机库,正在将我的json作为char *返回。我想在c#中做的是使用此指针并将其直接写入this.ControllerContext.HttpContext.Response ....
考虑此多边形结构,该结构最多可存储64个索引点和可枚举点:公共不安全结构多边形:IEnumerable {私人固定...
如何使用rest api laravel处理我密码中的不安全字符(“ <>#%{} | \ ^〜[]`”)。例如:<
我从磁盘上读取了一个巨大的图像(例如1.800MP @每像素16位)。 Magick.Net为我提供了一个1D字节的数组,因此每个像素都是数组中的2个元素。我需要一个ushort的二维数组,用于...
如何避免不必要的匹配检查或在从实现Drop特性的结构中移动值时使用不安全的方法
我具有使用方法do_something实现特征Trait的结构B。如果尚未调用struct B,则需要执行一些其他操作。 ...
我编写了代码:public class StaticBooleanDemo {private static boolean flag;公共静态布尔型getFlag(){返回标志; } public static void main(String [] args)抛出...
为什么Java Unsafe CAS(getAndAddInt)比手动编写的代码要快
我通过手动而不是直接调用Unsafe.getAndAddInt方法编写了cas代码(compare_and_set的while循环)。但是,当我使用jmh测试性能时,它显示出很大的性能损失...