3

Iirc from C, you can have a statement along these lines:

char* str = "1234";
int nonStr = *((int*)str);

(I intentionally made the string 4 characters so in the average scenario it will have the same number of bytes as the integer.) This will dereference the memory where str is stored and give you the value if it was an integer (522207554 if I did the conversion right).

Is there any way to do the same thing in C#? I know this is a low level memory operation which is generally blissfully hidden from the C# programmer, I am only doing this for a teaching exercise.

just.another.programmer
  • 8,579
  • 8
  • 51
  • 90
  • 1
    A 'teaching' exercise! Surely we'd want to encourage good habits and not to abuse pointers like this - especially in C#. If you want to teach pointer abuse, at least do it in a context that's appropriate - C/C++ in a low level/OS environment. Not C#. – Skizz Feb 08 '14 at 23:16
  • possible duplicate of [.NET String to byte Array C#](http://stackoverflow.com/questions/472906/net-string-to-byte-array-c-sharp) – w.b Feb 08 '14 at 23:16
  • @Skizz the whole point of abusing them is to "point" out that they can be abused, even accidentally. I want to explain what's going on in memory behind the scenes so the students will understand why they get an `InvalidCastException`! I don't intend to teach them to ever write "real" programs this way. – just.another.programmer Feb 08 '14 at 23:20
  • There are `IntPtr` objects in .NET and you can do pointer manipulation inside `unsafe` blocks. What pointer are you trying to manipulate to begin with? Unless it's an IntPtr, something marshaled or a pointer created inside an unsafe block, I don't think there's anything you can do with it as far as low level memory manipulation goes. – vane Feb 08 '14 at 23:21
  • That's my point. Use C as the tool to explain how memory works, and then talk about how C# abstracts the memory interface into more strictly controlled access that leads to InvalidCast. Teaching them how to abuse pointers in C# and they'll resort to doing it when they hit a problem rather than refactoring and improving the design. It's kinda like using `goto` in C++, it just leads to this: http://xkcd.com/292/ – Skizz Feb 08 '14 at 23:37
  • C code like that formally invokes undefined behavior. – icktoofay Feb 09 '14 at 05:58
  • 1
    @just.another.programmer: `str` points to a statically-allocated array of `char`s, and the strict aliasing rule says (approximately) that you can't access an object of one type through a pointer to a different type (with a few exceptions that this does not fall into). This permits certain optimizations that are sometimes desirable. The code in your question could have its undefined behavior removed by using `memcpy(&nonStr, str, sizeof(nonStr))`. (This invokes one of the allowable exceptions—non-`char` things can be used as `char`, but not vice-versa.) More information is available elsewhere. – icktoofay Feb 13 '14 at 04:00

3 Answers3

6

You can do this using unsafe context and fixedstatement:

static unsafe void Main(string[] args)
{
    string str = "1234";
    fixed(char* strPtr = str)
    {
        int* nonStr = (int*)strPtr;
        Console.WriteLine(*nonStr);
    }
}

prints

3276849
MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
  • `char` in C# is a two-byte struct (UTF-16 encoding), so you'd want **2** characters in a string. You can see that here: 3276849 in hex is 0x00320031 ("34" weren't copied). – Carl Walsh Nov 10 '17 at 00:30
1

You're looking for the unsafe functionality of C#.

Here's one reference. A general search for "C# unsafe pointer dereference" turns up many results.

Erik Noren
  • 4,279
  • 1
  • 23
  • 29
0

Would a union simulation be sufficient for this?

http://msdn.microsoft.com/en-us/library/acxa5b99.aspx

user3288049
  • 114
  • 1
  • 6