c# pointers vs IntPtr

21,539

Solution 1

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.

Solution 2

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.

Solution 3

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.

Solution 4

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);

}
Share:
21,539
Ali Tarhini
Author by

Ali Tarhini

Computer Engineer & Scientist

Updated on January 08, 2021

Comments

  • Ali Tarhini
    Ali Tarhini over 3 years

    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?

  • Ali Tarhini
    Ali Tarhini over 13 years
    in fact there is using Marshalling
  • Guffa
    Guffa over 13 years
    @Ali Tarhini: That's just calling a method that uses unsafe code for you. The point is that unsafe code has to be used in the end, there is no way to access the data otherwise.
  • Guffa
    Guffa over 11 years
    That's not the difference between a pointer and an IntPtr. A pointer doesn't have to be typed, it can just as well be an untyped pointer, i.e. a void*. The differece is that an IntPtr is not a pointer at all.
  • Guffa
    Guffa over 8 years
    Why the downvote? If you don't explain what it is that you think is wrong, it can't improve the answer.