你应该在C#代码中使用指针吗?有什么好处?它是由The Man(微软)推荐的吗?
在C#中使用unsafe关键字使用指针会产生什么后果(正面/负面)?例如,什么是垃圾收集,性能增益/损失是什么,与其他语言手动内存管理相比,性能增益/损失是什么,危险是什么,在哪种情况下使用这种语言是合理的功能,编译时间更长......?
在Java中,有没有办法获得参考地址,比方说
String s = "hello"
Run Code Online (Sandbox Code Playgroud)
我可以获取s本身的地址,也可以获取引用引用的对象的地址吗?
有人能举例说明在C#代码中实际使用"不安全"和"修复"的好时机吗?我以前玩过它,但从来没有真正找到它的好用.
考虑这段代码......
fixed (byte* pSrc = src, pDst = dst) {
//Code that copies the bytes in a loop
}
Run Code Online (Sandbox Code Playgroud)
与简单使用...相比
Array.Copy(source, target, source.Length);
Run Code Online (Sandbox Code Playgroud)
第二个是.NET Framework中的代码,第一部分是从Microsoft网站复制的代码,http://msdn.microsoft.com/en-us/library/28k1s2k6(VS.80).aspx.
内置的Array.Copy()比使用Unsafe代码要快得多.这可能只是因为第二个只是更好的编写,第一个只是一个例子,但你真的甚至需要使用不安全/固定代码的什么样的情况?或者,这个可怜的网络开发人员是否在弄乱他的头脑?
我需要使用SecureString
微软的课程,我在互联网上找到以下代码:
public static class SecureStringExt
{
public static SecureString ConvertToSecureString(this string password)
{
if (password == null)
throw new ArgumentNullException("password");
unsafe //Red highlighted line
{
fixed (char* passwordChars = password)
{
var securePassword = new SecureString(passwordChars, password.Length);
securePassword.MakeReadOnly();
return securePassword;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
唯一的问题是unsafe
关键字一直让我错误说Cannot use unsafe construct in safe context
.不幸的是我找不到为什么会这样......
注意: 上面的代码在LINQPad中运行,但在VS2013中没有(使用resharper).
出于教育目的,我正在编写一组方法,这些方法会导致C#中的运行时异常,以了解所有异常是什么以及导致它们的原因.现在,我正在修补导致问题的程序AccessViolationException
.
对我来说最明显的方法是写入受保护的内存位置,如下所示:
System.Runtime.InteropServices.Marshal.WriteInt32(IntPtr.Zero, 0);
Run Code Online (Sandbox Code Playgroud)
正如我所希望的那样,这引起了人们的注意AccessViolationException
.我想更简洁地做到这一点,所以我决定用不安全的代码编写程序,并通过分配0
零指针来做(我认为的)完全相同的事情.
unsafe
{
*(int*)0 = 0;
}
Run Code Online (Sandbox Code Playgroud)
由于无法理解的原因,这引发了一个问题NullReferenceException
.我玩了一些,并发现使用*(int*)1
而不是抛出一个NullReferenceException
,但如果你使用负数,就像*(int*)-1
它会抛出一个AccessViolationException
.
这里发生了什么?为什么*(int*)0 = 0
导致a NullReferenceException
,为什么不导致AccessViolationException
?
假设我想要一个7字节(或3或777)的值类型.
我可以这样定义:
public struct Buffer71
{
public byte b0;
public byte b1;
public byte b2;
public byte b3;
public byte b4;
public byte b5;
public byte b6;
}
Run Code Online (Sandbox Code Playgroud)
定义它的一种更简单的方法是使用固定缓冲区
public struct Buffer72
{
public unsafe fixed byte bs[7];
}
Run Code Online (Sandbox Code Playgroud)
当然第二个定义更简单.问题在于必须为固定缓冲区提供unsafe关键字.我知道这是使用指针实现的,因此不安全.
我的问题是为什么它必须是不安全的?为什么C#不能提供任意常量长度数组并将它们保存为值类型而不是使其成为C#引用类型数组或不安全缓冲区?
我正在编写一个图像处理程序来执行视频帧的实时处理.它是在C#中使用包装OpenCV库dll(非托管C++)的Emgu.CV库(C#).现在我必须编写自己的特殊算法,它需要尽可能快.
哪个算法的实现速度更快?
在C#中编写'不安全'函数
将该函数添加到OpenCV库并通过Emgu.CV调用它
我猜C#unsafe比较慢,因为它是通过JIT编译器,但差异是否显着?
编辑:
在VS2008下编译为.NET 3.5
我遇到了一个情况,我有一个非常大的文件,我需要从中读取二进制数据.
因此,我意识到.NET中的默认BinaryReader实现非常慢.用.NET Reflector查看它后,我发现了这个:
public virtual int ReadInt32()
{
if (this.m_isMemoryStream)
{
MemoryStream stream = this.m_stream as MemoryStream;
return stream.InternalReadInt32();
}
this.FillBuffer(4);
return (((this.m_buffer[0] | (this.m_buffer[1] << 8)) | (this.m_buffer[2] << 0x10)) | (this.m_buffer[3] << 0x18));
}
Run Code Online (Sandbox Code Playgroud)
这让我觉得非常低效,想到自32位CPU发明以来计算机是如何设计用于32位值的.
所以我使用这样的代码创建了我自己的(不安全的)FastBinaryReader类:
public unsafe class FastBinaryReader :IDisposable
{
private static byte[] buffer = new byte[50];
//private Stream baseStream;
public Stream BaseStream { get; private set; }
public FastBinaryReader(Stream input)
{
BaseStream = input;
}
public int ReadInt32()
{
BaseStream.Read(buffer, 0, 4);
fixed …
Run Code Online (Sandbox Code Playgroud) 在Javadoc for Object.hashCode()中声明
尽管合理实用,但是由class定义的hashCode方法
Object
确实为不同的对象返回了不同的整数.(这通常通过将对象的内部地址转换为整数来实现,但Java™编程语言不需要此实现技术.)
这是一个常见的miconception,这与内存地址有关,但它并没有因为它可以在没有通知的情况下改变,而hashCode()不会,也不能改变对象.
@Neet提供了一个很好的答案的链接/sf/answers/39579151/但我正在寻找更多细节.
这是一个例子来说明我的担忧
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
for (int t = 0; t < 10; t++) {
System.gc();
Object[] objects = new Object[10];
for (int i = 0; i < objects.length; i++)
objects[i] = new Object();
for (int i = 0; i < objects.length; i++) {
if (i > 0) System.out.print(", ");
int location = unsafe.getInt(objects, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * i);
System.out.printf("%08x: hc= …
Run Code Online (Sandbox Code Playgroud) unsafe ×10
c# ×8
pointers ×4
.net ×2
fixed ×2
java ×2
memory ×2
performance ×2
arrays ×1
binaryreader ×1
c++ ×1
coding-style ×1
hashcode ×1
jvm ×1
keyword ×1
low-level ×1
securestring ×1
value-type ×1