Unsafe lack of pointers in C#?

  • Thread starter Thread starter Bradley1234
  • Start date Start date
B

Bradley1234

Sorry if this is obvious, but Ill ask...

Is there a new way of using pointer operations in C# ?

Ive got a Deitel book on C# that neither mentions the word "pointer" nor
"unsafe" in the index.

coming from a C/C++ world, pointers make perfect sense, and getting up to
speed on CS, did pointers go away?

To compile, one must inform the compiler the segment is "unsafe" ?

Thats okay, I can force unsafe/pointers, but is there a newer, better way??

mtia
 
In C++, pointers were a way of implementing things from the days of
procedural programming. You don't need them in C#. Use OO constructs
instead.

Can you give me an example of a situation where you'd think pointers are a
good thing, so I can give you some ideas of how to do this differently using
OO methods?

--- Nick
 
Hey thanks, that makes sense, but it just occured to me about pointers...

Ive got an example, where I stumbled into it

Class Ticket {
private Passenger *traveler;
}

Class Passenger {

private List<Ticket> tickets;

}

Class Seat {

private Passenger *occupant;

}

Im sure there is a buzzword for doing this, and Ill feel dumb when I hear
what it is, but when I tried to toss this into my C# code it complained and
said no, you must use "unsafe" to mark that kind of renegade code...
 
Hi Bradley,

Yes, you can use pointer operations in C# inside unsafe blocks.
I'm not sure but many books seem to skip this subject and perhaps with
good reason. Not being used to extensive use of pointers I find I rarely
need them when everything is object oriented from the ground up.

You need to specify /unsafe to compile code with unsafe blocks. An added
protection I suspect as you now are responsible for your own memory
handling.

This is the tutorial for unsafe blocks from the msdn documentations:

http://msdn.microsoft.com/library/d.../en-us/csref/html/vcwlkunsafecodetutorial.asp

In the end there isn't a 'new way' of using pointer operations in C#,
you just don't use pointer operations.
 
In this case you substitute pointers with references, sort of a pointer
that points to a memory address that holds the address to the actual
object. This memory address will be changed by the garbage collector.

class Ticket
{
private Passenger traveler; // no * needed, everything is basically a
reference
}

class Passenger
{
private Ticket[] tickets; // I may have misunderstood the List<>
}

class Seat
{
private Passenger occupant;
}

class Ticket
{
}
 
Use the .Net Framework SDK documentation. There is a tutorial on how to use
unsafe (pointers) in C#.

ms-help://MS.NETFrameworkSDKv1.1/csref/html/vcwlkUnsafeCodeTutorial.htm

Lloyd Sheen
 
Morten said:
private Ticket[] tickets; // I may have misunderstood the List<>

I think he meant templates... in C# you don't have this feature. Not
until C# 2.0 when generics will be introduced... (generics in c# are
like templates in C).

Until then you have 2 options: You can create a Collection of objects of
your choice, or you can use any of the collections in System.Collections
or System.Collections.Specialized. The ArrayList class is the most
common... like:

private ArrayList tickets;
 
Hey thanks Nick, Morten, Lloyd and Natan, seems like there is a rare time
when pointers are needed, and yes it was a template <> thats apparently not
covered until v.2?

Im going to be using older COM objects, or try to anyway and will probably
be trying things there next.

All this nice OOP has made me sort of forget pointers, references address
of, using malloc... When the C# intellisense helps fill out the
statements? oh, what a feeling.

Lloyd Sheen said:
Use the .Net Framework SDK documentation. There is a tutorial on how to use
unsafe (pointers) in C#.

ms-help://MS.NETFrameworkSDKv1.1/csref/html/vcwlkUnsafeCodeTutorial.htm

Lloyd Sheen
 
In C++, pointers were a way of implementing things from the days of
procedural programming. You don't need them in C#. Use OO constructs
instead.

Can you give me an example of a situation where you'd think pointers are a
good thing, so I can give you some ideas of how to do this differently using
OO methods?

--- Nick

OK, here's one I'm curious about. Say you have a string or an array, and
you want to send a reference to the 5th element to another function. You
don't want to slow things down by copying anything.

C++:

char * test = "This is an example test";

void AlterTenChars(char * instring) {
for (int x = 0; x < 10; x++)
instring[x] = 'x';
}

void main() {
AlterTenChars(&(test[4])); // <<< pointer to 5th element
}

-------

OK, I know you could cheat and send a ref to the string and a starting
index, but there are places where I've needed to do something like the
above. I've ended up with 'unsafe' and 'fixed'. What's the
fastest-running C# equivalent, without using 'unsafe/fixed'?

PS: I'm sure I missed something in the C++ syntax. You get the point
though.
 
_BNC... I have no idea if this is optimized. Remember that strings are
immutable, so I have used a stringbuilder.

using System;
using System.Text;

namespace TestChar
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{

// not optimized
static void AlterTenChar(StringBuilder inString, int index)
{
for (int i=index; i<inString.Length && i<(index+10);i++)
{
inString= 'x';
}
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
StringBuilder test= new StringBuilder("Hello World");
Class1.AlterTenChar(test,4);
System.Console.WriteLine(test);
System.Console.ReadLine();

}
}
}


Regards,
Jeff
OK, here's one I'm curious about. Say you have a string or an array,
and you want to send a reference to the 5th element to another function.
You don't want to slow things down by copying anything.<
 
Pointers can be used in unsafe code blocks from C#. The framework however
provides "safe" ways of accessing memory directly through the Marshal class
that has methods to read and write bytes and copy memory. Because VB has no
concept of pointers this is the method used by many of my graphics
demonstrations on my site.

Personally I have no fear of the unsafe keyword so I use it often in C# when
the architecture seems to require it. I also use Marshal to get around my
readers fear of the unsafe.

The following snippets of code shows the same operations performed with
unsafe code in C# and marshal in VB. They are functionally identical and if
you wished to use Marshal in C# the overheads don't seem to be excessive.

BitmapData bmd=bm.LockBits(new Rectangle(0, 0, 10, 10),
System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat);
int PixelSize=4;



for(int y=0; y<bmd.Height; y++)

{

byte* row=(byte *)bmd.Scan0+(y*bmd.Stride);

for(int x=0; x<bmd.Width; x++)

{

row[x*PixelSize]=255;

}

}

Dim x As Integer

Dim y As Integer

Dim PixelSize As Integer = 4

Dim bmd As BitmapData = bm.LockBits(new Rectangle(0, 0, 10, 10),
System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat)

For y = 0 To bmd.Height - 1

For x = 0 To bmd.Width - 1

Marshal.WriteByte(bmd.Scan0, (bmd.Stride * y) + (4 * x) , 255)

Next

Next


--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
Pointers can be used provided you compile the program with a /unsafe
switch and declare the pointer within an unsafe block.

with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- http://www.411asp.net/func/search?
qry=Ravichandran+J.V.&cob=aspnetpro
- http://www.southasianoutlook.com
- http://www.MSDNAA.Net
- http://www.csharphelp.com
- http://www.poetry.com/Publications/
display.asp?ID=P3966388&BN=999&PN=2
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 
Since arrays are reference types, you can simply pass the entire array
if you need to change more than one element. Nothing will be copied.

-------

// example uses int array instead of string, because strings are
immutable
public void AlterTenInts(int[] array)
{
for (int i = 0; i < 10; i++)
array = 12345;
}

public void TestIt()
{
int[] myArray = new int[10];
AlterTenInts(myArray);
}

-------

And if you only need to change one element, you can use a ref parameter
(equivalent to a reference in C++ or a var parameter in Pascal):

-------

public void AlterInt(ref int x)
{
x = 12345;
}

public void TestIt()
{
// pass a reference to an array element
int[] myArray = new int[10];
AlterInt(ref myArray[0]);

// pass a reference to a local variable
// (it must be initialized first)
int foo = 123;
AlterInt(ref foo);
}
 
Since arrays are reference types, you can simply pass the entire array
if you need to change more than one element. Nothing will be copied.

// example uses int array instead of string, because strings are
immutable
public void AlterTenInts(int[] array)
{
for (int i = 0; i < 10; i++)
array = 12345;
}

public void TestIt()
{
int[] myArray = new int[10];
AlterTenInts(myArray);
}


I had posited the original schenario with the hope that readers would
understand the extension of the concept. My fault for not explaining well
enough. I'll try again.

Assume that you are linearly parsing a loaded stream (array) of 10000000
(that's a gazillion) *variable length* data packets. The first 4 bytes of
each packet tell how long the packet is, but they're encoded. In C++,
you'd simply pass the address of the 'length' packet to the decoder() and
get the decoded number back.

Yes, you could pass the reference to the entire huge array with an index
of 5666600003 or whatever, just to get at those 4 bytes. But that's ugly,
ain'it?

I invariably see this type of thing handled by 'unsafe/*/fixed'.

It's not necessarily a 'flaw' per se, but there is a certain switch-point
where the language can start looking awkward. At that point, I start
thinking about how to get around the language syntax. C# does allow
those loopholes, fortunately, or I probably wouldn't use it.
 
I had posited the original schenario with the hope that readers would
understand the extension of the concept. My fault for not explaining well
enough. I'll try again.

Assume that you are linearly parsing a loaded stream (array) of 10000000
(that's a gazillion) *variable length* data packets. The first 4 bytes of
each packet tell how long the packet is, but they're encoded. In C++,
you'd simply pass the address of the 'length' packet to the decoder() and
get the decoded number back.

Yes, you could pass the reference to the entire huge array with an index
of 5666600003 or whatever, just to get at those 4 bytes. But that's ugly,
ain'it?

or, better yet, your array would contain a gazillion OBJECTS. You would
pass a single object to the decoder.
I invariably see this type of thing handled by 'unsafe/*/fixed'.

That's just what you are used to. Objects are just as powerful and less
error prone.
It's not necessarily a 'flaw' per se, but there is a certain switch-point
where the language can start looking awkward. At that point, I start
thinking about how to get around the language syntax. C# does allow
those loopholes, fortunately, or I probably wouldn't use it.

I suppose that a model-T looked awkward to a person used to riding around in
a very swank horse-drawn buggy. The rest, as we say, is history.

--- Nick
 
or, better yet, your array would contain a gazillion OBJECTS. You would
pass a single object to the decoder.


That's just what you are used to. Objects are just as powerful and less
error prone.

That would be ideal, but I don't have any control over the input stream's
format. The structures are of variable length, so I can't even index into
a structure in the huge byte array. I have to walk thru it C-style,
byte-by-byte, parsing the length of each of the structures as I go.
I suppose that a model-T looked awkward to a person used to riding around in
a very swank horse-drawn buggy. The rest, as we say, is history.

--- Nick

Well, if you can think of a way around it, I'd love to hear it. I'm stuck
with the 'free-form' input byte stream format: [L = length designator]
[D=data]

[L1][L2][L3][L4][D1][D2][D3]
[L1][L2][L3][L4][D1][D2][D3][D4][D5]
[L1][L2][L3][L4][D1][D2]
[L1][L2][L3][L4][D1][D2][D3][D4][D5][D6]
[L1][L2][L3][L4][D1]
[L1][L2][L3][L4][D1][D2][D3]

SeewhadameanVern? In this case (and similar), I don't think that passing
a ref to the entire array along with a big index is any more elegant than
'breaking' C# by using unsafe/fixed to pass a pointer to the current
structure.
 
Yes, you could pass the reference to the entire huge array with an
index
What do you think you are doing with the pointers?
You are passing a reference. The reference points to a memory location in
your case.
If you don't refactor your program (see below) then passing "the entire
array" effectively does only this... it passes a pointer to the array.

On the other hand, I see no reason that you should keep a stream in an
array. Sounds kinda silly to me.

Reality check: if any of the data packets is NOT the correct length, then
the entire rest of the stream is forfeit. In other words, if a data packet
is supposed to be 50 bytes, and it is 48 bytes instead, then the two of the
length bytes for the next packet will be consumed. THe length of the next
packet would be wrong... and the rest of the chain as well.

Therefore, you get no Advantage for bringing the entire stream into an array
in the first place. Why allocate that much memory? Seems extremely
wasteful.

Why not just set up a stream reader that reads four bytes... converts to
length... and then reads that many bytes off of the stream, returning a data
packet.

The calling app would not be aware of the encoding at all. It would see a
stream of data packets, not a stream of bytes.

Then, your entire argument about passing pointers to a huge array goes away.

--- Nick
 
Back
Top