reza
reza

Reputation: 1379

Garbage Collection Annoyances - How to have a Ptr to an Obj keep the Obj alive? C#

I'm used to C and the use of pointers. I know you can do a lot of stuff with pointers in C# but the garbage collection is getting annoying. Is it possible to create a pointer to the object, and somehow link the pointer to the object so that as long as the pointer is alive, the object is not cleaned up? Something lie

unsafe void* Function1 () {
 SomeStruct s = new SomeStruct();
 void* ptr = (void*) &s;
 return ptr;
}

main() {
  void* p = Function1();
  p->field = 3;
}

When I tried to do this, the object was fine and the pointer worked inside Function1, but as soon as the function exited, the object was destroyed though the pointer was valid. It would be awesome if there was some way to link the two as far as the garbage collector was concerned.

Upvotes: 0

Views: 119

Answers (3)

Guffa
Guffa

Reputation: 700592

Assuming that your type SomeStruct is not very badly named, and is in fact a struct, then you are allocating memory for it on the stack.

When you return from the method, the stack frame where the struct is allocated is removed, so outside the method the struct simply doesn't exist any more. There is nothing you can do do keep the garbage collector from removing it, because it's not the gabage collector that removes it. It's returning from the method that does that.

Note that a struct in C# is a different concept from a struct in C. In C# a struct is always a value type, while in C it can either be a value type or reference type depending on how you use it.

If you want to keep the value, then you can box it to keep it on the heap. You return a reference to the boxed value, not a pointer, because the garbage collector doesn't care about pointers, only references:

object Function1 () {
  SomeStruct s = new SomeStruct();
  // box the value:
  object o = s;
  return o;
}

main() {
  object p = Function1();
  // unbox the value:
  SomeStruct s = ((SomeStruct)p);
  s.field = 3;
}

You can of course pass the struct around instead of putting it on the heap:

SomeStruct Function1 () {
  return new SomeStruct();
}

main() {
  SomeStruct p = Function1();
  p.field = 3;
}

If you really need to store the struct on the heap, then you should consider making it a class instead, then it automatically ends up on the heap.

Upvotes: 2

Jason Williams
Jason Williams

Reputation: 57922

A pointer that is reference-counted and stops the allocation being garbage collected until it's no longer in use is a reference. Use references and you are extremely unlikely to have any need for pointers or unsafe code at all.

C# is not C, so beware of trying to write C code - you need to learn C# and realise that there are some very large differences between the languages despite their apparent similarities.

Upvotes: 1

Alexei Levenkov
Alexei Levenkov

Reputation: 100545

Assuming SomeStruct is actually struct than it is value type and in your particular case it is allocated on stack. Note that struct in C and struct in C# have different meaning.

Upvotes: 1

Related Questions