是否可以在C#中执行以下操作?
unsafe string GetName()
{
Foo[] foo = new Foo[2]; // Create an array of Foo and add two Foo elements
foo[0] = new Foo { Name = "Bob" };
foo[1] = new Foo { Name = "Jane" };
Foo *ptr = &foo; // Get address of the first element in the array
ptr++; // Move to the next element in the array
return *ptr.Name; // Expect Name to be "Jane"
}
Run Code Online (Sandbox Code Playgroud)
我正在玩自定义数据结构,我希望能够做到这一点.
我知道你可以用int类型等来做,但是用户定义的结构和类呢?
在Rust中填充结构向量的好方法是:
理想情况下
unsafeC等价物是:
struct MyStruct *create_mystruct(const uint n) {
struct MyStruct *vector = malloc(sizeof(*vector) * n);
for (uint i = 0; i < n; i++) {
/* any kind of initialization */
initialize_mystruct(&vector[i], i);
}
return vector;
}
Run Code Online (Sandbox Code Playgroud)
我正在移植一些C代码,它在一个简单的循环中填充一个数组,所以我想知道是否有一种乡村方式来执行这样一个零或至少最小开销的常见任务?
如果此代码的Rust版本通常需要一些额外的检查,那么最近的等价物是什么?
在 Java 8 之前,可以sun.misc.Unsafe通过如下方法获取单例实例:
public static Unsafe getUnsafe() {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
尽管强烈建议不要使用Unsafe,但许多供应商和图书馆在内部使用它。
现在,有了 Java 9 和 Jigsaw,我认为Unsafe处理方式也发生了变化。我读了一些带有相反信息的帖子。有人说它已完全隐藏,甚至无法检索,有人说必须启用 VM 标志,而另一些人则写道它现在应该得到正式支持。
那么:是否仍然可以sun.misc.Unsafe在 Java 9 中使用?如果可以,如何使用?
我正在编写一个应用程序,它必须从文件中找到子字符串并将该子字符串写入某个不同的文件中。为了写入文件,我使用 fputs,但有人告诉我检查更安全的版本来写入文件。
while (fgets(line, MAX_LINE_LEN, fp1) != NULL) {
if (pname_count < 1) {
if (strstr(line, p_name)) {
pname_count++;
fputs(strstr(line, p_name), fp2);// danger.
continue;
}
}
//Remaining code
}
Run Code Online (Sandbox Code Playgroud)
按照下面的两个链接,但没有得到我的确切答案。
有人可以解释一下安全方面“fputs”的漏洞是什么吗?
由于 fwrite 需要写入文件的字符数,这是否会使 fwrite 比 fputs 更安全?
我正在尝试尽可能多地优化对u32来自u8. 因此,我正在测试不同的选项(for 循环、迭代器、使用 ByteOrder crate 等)作为这些测试的一部分,我还想检查是否可以使用from_raw_parts标准函数改进它。这是我的代码:
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;
fn main(){
let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
let random_bytes = random_bytes.as_slice();
let view = &random_bytes as *const _ as *const u32;
let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
println!("{:x?}", slice);
println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", &random_bytes[0..4]);
}
Run Code Online (Sandbox Code Playgroud)
我本来希望两个小端或大端中的至少一个等于第一个打印,但事实并非如此,例如示例输出
[d951db30]
143600ff
ff003614
[ff, 0, 36, 14]
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
代码是:
package main
import (
"fmt"
"unsafe"
)
type Point struct {
x int
y int
}
func main() {
buf := make([]byte, 50)
fmt.Println(buf)
t := (*Point)(unsafe.Pointer(&buf))
t.x = 10
t.y = 100
fmt.Println(buf)
}
Run Code Online (Sandbox Code Playgroud)
运行它时,会发生运行时恐慌:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0xa pc=0x43dd4d]
Run Code Online (Sandbox Code Playgroud)
为什么?
use std::sync::Arc;
use std::sync::atomic::{AtomicPtr, Ordering};
use std::thread;
fn main() {
let mut arr = vec![1,2,3];
let ptr = &mut arr as *mut Vec<i32>;
println!("ptr : {:?}",ptr);
// unsafe { (*ptr)[0] = 2; }
let ptr_ref_1 = Arc::new(AtomicPtr::new(ptr));
let a = thread::spawn(move || unsafe {
let ptr_inner = (ptr_ref_1).load(Ordering::SeqCst);
println!("ptr_inner_1 {:?}",ptr_inner);
(*ptr_inner).push(4);
println!("4 is done");
});
let ptr_ref_2 = Arc::new(AtomicPtr::new(ptr));
let b = thread::spawn(move || unsafe {
let ptr_inner = (ptr_ref_2).load(Ordering::SeqCst);
println!("ptr_inner_2 {:?}",ptr_inner);
(*ptr_inner).push(5);
println!("5 is done");
});
let ptr_ref_3 = …Run Code Online (Sandbox Code Playgroud)
fn test() -> *const Vec<u8> {
let b = vec![9_u8];
let ret: *const Vec<u8> = &b;
println!("ret ptr={:#p} inside {:#p}", ret, b.as_ptr());
std::mem::forget(b);
ret
}
fn main() {
let a = test();
let v = unsafe {
&*a
};
println!("ret ptr={:#p} inside {:#p} value={}", v, v.as_ptr(), v[0]);
println!("ret ptr={:#p} inside {:#p} value={}", v, v.as_ptr(), v[0]);
}
Run Code Online (Sandbox Code Playgroud)
我的机器给出了:
ret ptr=0x00007fffc5d85690 inside 0x00005650a61cfaa0
ret ptr=0x00007fffc5d85690 inside 0x00005650a61cfaa0 value=9
ret ptr=0x00007fffc5d85690 inside 0x00005650a572a348 value=76
Run Code Online (Sandbox Code Playgroud)
最后一行的问题是值突然改变,这是某种错误吗?
我需要将一个C#字符串复制到一个char*.我有这个代码,它有效,但看起来很笨拙.有没有更优雅的方式来做到这一点?
public unsafe static void GetReply(char* buffer) {
string reply = "Hello, world"; // or whatever
// clumsy code:
var i = buffer;
foreach (char x in reply.ToCharArray()) {
*i = x;
i++;
}
*i = '\0';
}
Run Code Online (Sandbox Code Playgroud)
注意:buffer保证指向已知长度的已分配内存.没有问题.
在下面的代码中,我使用不安全代码将不可变引用转换为可变指针,然后尝试通过该可变指针编辑内部值。
fn main() {
#[repr(transparent)]
struct Item(isize);
impl Item {
#[inline]
fn ptr(&self) -> *mut isize {
self as *const Item as *mut isize
}
fn increment(&self) {
let val = self.0 + 1;
unsafe {std::ptr::write(self.ptr(), val)}
}
}
let item = Item(22);
println!("before = {}", item.0);
item.increment();
println!("after = {}", item.0);
}
Run Code Online (Sandbox Code Playgroud)
当我在调试模式下编译它时,结果符合预期,并且值确实增加了。然而,在发布模式下,尽管该部分代码运行,但该值根本不增加。此外,以下其他类型的值变异似乎也不起作用
unsafe {*&mut *(self.ptr()) += 1;}
std::mem::replace()
std::mem::swap()
unsafe ×10
rust ×5
pointers ×3
c# ×2
arrays ×1
c ×1
endianness ×1
go ×1
java ×1
java-9 ×1
memory ×1
native ×1
performance ×1
raw-pointer ×1
reflection ×1
slice ×1
string ×1
vector ×1