3

I have an array that works more or less like a hastable: based on an index, a value will be placed in the array, so some indices of the array will have values inside, others might not or will not. I have two pieces of code:

public void register( int index, string value )
{
    _array[index] = value;
}
public void unregisterAll( )
{
    /*
    is this going to cause a memory leak when some of the values
    are filled int the above function?
    */
    _array = new string[12];
}
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
GeekPeek
  • 1,615
  • 1
  • 20
  • 34

1 Answers1

8

C# uses a garbage collector. If an object is no longer referenced it is (after some time) free'd automatically.

This is what happens (from the perspective of the garbage collector (GC)) when you execute unregisterAll()

object_array`1: referenced by _array
// execute unregisterAll();
create object_array`2 and let _array reference it
// Some time later when the GC runs
object_array`1: not referenced
object_array`2: referenced by _array
// Some time later, when the GC decided to collect
collect object__array`1

Note that this doesn't mean you cannot have a memory leak in C#. Some objects use unmanaged resources which need to be disposed manually (they implement the interface IDisposable which you can dispose of automatically by scoping it in a using block:

using(IDisposable disposable = new ...)
{
    // use it
} // when leaving this scope disposable.Dispose() is automatically called

Or which you can dispose of manually by calling Dispose() on them.

Roy T.
  • 9,429
  • 2
  • 48
  • 70
  • thank you for your clear answer. Just to be safe, in this example I used strings but in my project I used structs. The same thing goes for structs right? (provided they are not referenced somewhere else in the project). – GeekPeek Nov 19 '15 at 09:28
  • 1
    Arrays are allocated on the heap, be them reference or values types. If you re-assign the array to point to a new array, this won't cause any memory leaks. The objects will simply be collected once a collection of the proper generation kicks in. – Yuval Itzchakov Nov 19 '15 at 09:29
  • @GeekPeek As Roy updated his answer your only need to take care if objects are disposable - this is implementing the interface IDisposable. These objects need to be disposed to properly free up memory. Eighter by calling their Dispose() method directly or by use the using keyword which also calls Dispose(). Re-assigning a array which contains disposable elements need to iterate over them and call their `Dispose()`. All other arrays can simply be re-assigned and left to the GC to take care. – Marc Nov 19 '15 at 09:37
  • Makes sense. Thanks :) – GeekPeek Nov 19 '15 at 09:39
  • @Marc: While it is true that you should call `Dispose` on `IDisposable` objects to enforce deterministic resource cleanup this will not free up any managed managed memory. It will only release unmanaged resources which may include unmanaged memory but usually are handles to operating system objects like files and sockets. – Martin Liversage Nov 19 '15 at 09:49
  • @MartinLiversage Don't get your point. The managed part of the objects get freed by the GC as Roy wrote (if no refs are hold somewhere else). No problem there with simply re-assigning arrays. The only situation one have to take is is if the elements within an array are disposable objects. .. ok, GC will kick their Dispose() somewhen later too but that's bad practice to count on that. Did you mean that? – Marc Nov 19 '15 at 09:54
  • @Marc the Garbage collector NEVER calls dispose for you http://stackoverflow.com/questions/1691846/does-garbage-collector-call-dispose – Roy T. Nov 19 '15 at 10:01
  • @RoyT. You're right: the GC calls the finalizer and the finalizer 'should' call Dispose() but that was not my point. My point was that if one fill's IDisposable element to the array they need to be disposed manually before re-assigning the array. Using-keyword is great but may not work here as the array get's filled with elements some time before and re-assigned any time later on. So he may need a foreach loop to dispose the items manually. – Marc Nov 19 '15 at 10:13
  • @Marc: I see a lot of confusion around `IDisposable` and your statement _These objects need to be disposed to properly free up memory_ is not correct unless the unmanaged resource being disposed is unmanaged memory but in general that is not the case. I am just trying to remove some of the confusion. – Martin Liversage Nov 19 '15 at 10:21