如果考虑C#指针"不安全,"这是否意味着C ++指针是"不安全"太?

时间:2016-05-15 16:16:18

标签: c# c++ arrays pointers unsafe

我正在用C#做一个项目,它可以从线性代数包中受益。我看过那些那些,但我真的不想付钱,或者我发现它们不是很好。所以我决定写自己的。

我读到C ++数组比C#数组快得多,但是在C#中使用指针数组可以获得类似的性能,尽管它们被认为是“不安全的”。我很想知道C ++指针的不同之处,以及" unsafe-ness"也适用于C ++,或者它们是两个根本不同的东西。

4 个答案:

答案 0 :(得分:9)

C#(不安全)指针和C ++(原始)指针都具有以下特征:

  • 它们允许您引用给定地址空间中的地址。
  • 它们允许您对它们执行简单的算术运算(加法和减法),将整数作为偏移量。
  • 它们允许您取消引用它们指向的特定类型的数据。
  • 错误使用它们可以调用未定义的行为,使您完全有责任确保正确使用它们。

从这个意义上讲,无论是什么微小差异(如语法,固定等),C#指针和C ++指针几乎都是相同的编程概念。因此,它们几乎同样适用于静态分析,因此它们同样安全或不安全。因此,C#显式地将此构造称为unsafe这一事实并不能使等效的C ++构造“安全”。相反,使用“不安全”代码的能力在C ++中“永远在线”。

作为示例,请考虑使用超出范围的索引尝试访问数组的情况:

  • 使用C#数组时,在使用索引器语法时会出现异常,并且在使用指针和偏移量时将调用未定义的行为。
  • 使用C ++中的C风格数组时,在使用索引器语法或指针和偏移量时,将调用未定义的行为(因为这两种语法对于C风格的数组是等效的。)
  • 使用C ++ 11 std::array时,使用array::at时会出现异常,并且在使用索引器语法时会调用未定义的行为。

答案 1 :(得分:2)

粗略地说(并且它是非常粗略近似),C#unsafe指针与C ++指针是相同的。

对于这两者,程序员有更多的责任要做到正确,而对于正常的C#,如果你弄错了,最糟糕的情况是会抛出异常。运行时检查可以保证性能,但是如果你关闭它们 - 你就可以自己动手了。

答案 2 :(得分:2)

unsafe表示.Net授予您访问您未必分配的内存的权限。绑定检查已关闭,允许在JIT编译器中进行一些优化。

通常,指针在C ++中是相同的,即它们允许您访问任何内存区域。您可以使用运算符重载实现 bound-checking ,但它不是指针的默认值。

答案 3 :(得分:2)

特别是,C#中的不安全意味着可以突破托管沙箱并执行本机代码。这意味着您的托管代码可以生成非托管崩溃。这也是为什么没有完全信任就不允许使用不安全代码的原因(但您可能不再需要处理部分信任代码)。

您可能正在考虑如何在C#中使用int *运行非托管代码。容易:故意堆叠粉碎。将它分配给堆栈上的整数地址,并将包含本机代码的字节数组的地址写入下几个整数。