简体   繁体   中英

c# pointers vs IntPtr

this is the 2nd part of the 1st question using c# pointers

so pointers in c# are 'unsafe' and not managed by the garbage collector while an IntPtr is a managed object. but why use pointers then? and when it is possible to use both approaches interchangeably?

The CLI distinguishes between managed and unmanaged pointers. A managed pointer is typed, the type of the pointed-to value is known by the runtime and only type-safe assignments are allowed. Unmanaged pointers are only directly usable in a language that supports them, C++/CLI is the best example.

The equivalent of an unmanaged pointer in the C# language is IntPtr . You can freely convert a pointer back and forth with a cast. No pointer type is associated with it even though its name sounds like "pointer to int", it is the equivalent of void* in C/C++. Using such a pointer requires pinvoke, the Marshal class or a cast to a managed pointer type.

Some code to play with:

using System;
using System.Runtime.InteropServices;

unsafe class Program {
    static void Main(string[] args) {
        int variable = 42;
        int* p = &variable;
        Console.WriteLine(*p);
        IntPtr raw = (IntPtr)p;
        Marshal.WriteInt32(raw, 666);
        p = (int*)raw;
        Console.WriteLine(*p);
        Console.ReadLine();
    }
}

Note how the unsafe keyword is appropriate here. You can call Marshal.WriteInt64() and you get no complaint whatsoever. It corrupts the stack frame.

IntPtr is a managed object but the object it is pointing to is still not garbage collected. Using unsafe pointers in C# is really something that you should avoid. Code using unsafe pointers might not account for differences in memory addresses between x86 and x64 systems. It allows you to directly manipulate memory addresses easily which is not the case with IntPtr as you would need to marshal between the pointer and the actual structure stored at this memory address. With unsafe pointers you could directly work with the underlying type: here's a blog post I wrote illustrating one possible use of unsafe pointers. Another common example is manipulating image pixels directly.

An IntPtr can't be used as a replacement for a pointer.

The IntPtr just contains a numerical value, so you can't use it to access any data. Hence the name; it's an integer value with the same size as a pointer. You need to turn the value into a pointer to access the data that it points to, so there is no way to access the data without using unsafe code.

Note also that IntPtr is a structure, not an object, so the garbage collector isn't directly concerned with it at all.

Dereferencing data pointed to by a IntPtr is this simply sticking the number of the IntPtr into the address of an unsafe ptr as below

unsafe{

IntPtr p = new MyStruct("fred");    

myStruct * sptr;

sptr=p;

Console.WriteLine(*sptr->name);

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM