1

Sorry for being confused, at C++ I know to return local variable's reference or pointers can cause bad_reference exception. I am not sure how it is in C# ?

e.g

List<StringBuilder> logs = new List<StringBuilder>();
void function(string log)
{
   StringBuilder sb = new StringBuilder();
   logs.Add(sb);
}

at this function a local object is created and stored in a list, is that bad or must be done in another way. I am really sorry for asking this, but I am confused after coding C++ for 2 months.

Thanks.

icaptan
  • 1,495
  • 1
  • 16
  • 36
  • Your code is perfectly valid. Weird, but valid. – D Stanley Jul 23 '12 at 17:00
  • lol, yes it is weird because I wrote it here :) such functions works mostly, but i need whether they are safe – icaptan Jul 23 '12 at 17:03
  • Huh? This is not clear at at. That is an acceptable way to add StringBuilders to a StringBuilder List, although the SB will always be empty. Maybe your function should in a paramater for the text to add to the StringBuilder and in turn it adds it to the List. You can also shorten this code with logs.Add(new StringBuilder()); – GrayFox374 Jul 23 '12 at 17:05
  • Consider jumping straight to the point with `logs.Add(new StringBuilder());` – Wug Jul 23 '12 at 17:06
  • 1
    @icaptan: Please take a look at Lasse's answer on http://stackoverflow.com/questions/13049/whats-the-difference-between-struct-and-class-in-net – Jesse Hallam Jul 23 '12 at 17:06
  • thanks all ! you helped me a lot, I learned the answer. Maybe I am confused cause of being too tired :( Thank you all ! – icaptan Jul 23 '12 at 17:08

4 Answers4

1

Your C# code doesn't return an object reference so it doesn't match your concern. It is however a problem that doesn't exist in C#. The CLR doesn't let you create objects on the stack, only the heap. And the garbage collector makes sure that object references stay valid.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

In C#, the garbage collector manages all the (managed) objects you create. It will not delete one unless there are no longer any references to it.

So that code is perfectly valid. logs keeps a reference to the StringBuilder. The garbage collector knows this, so it will not clean it up even after the context in which it was originally created goes out of scope.

Sean U
  • 6,730
  • 1
  • 24
  • 43
1

In C# object lifecycle is managed for you by the CLR; compared to C++ where you have to match each new with a delete.

However in C# you can't do

void fun()
{
    SomeObject sb(10);
    logs.Add(sb);
}

i.e. allocating on the stack you have to use new - so in this respect both C# and C++ work similarly - except when it comes to releasing / freeing the object reference.

It is still possible to leak memory in C# - but it's harder than in C++.

Richard Harrison
  • 19,247
  • 4
  • 40
  • 67
1

There's nothing wrong with the code you've written. This is mostly because C#, like any .NET language, is a "managed" language that does a lot of memory management for you. To get the same effect in C++ you would need to explicitly use some third-party library.

To clear up some of the basics for you:

In C#, you rarely deal with "pointers" or "references" directly. You can deal with pointers, if you need to, but that is "unsafe" code and you really avoid that kind of thing unless you know what you're doing. In the few cases where you do deal with references (e.g. ref or out parameters) the language hides all the details from you and lets you treat them as normal variables.

Instead, objects in C# are defined as instances of reference types; whenever you use an instance of a reference type, it is similar to using a pointer except that you don't have to worry about the details. You create new instances of references types in C# in the same way that you create new instances of objects in C++, using the new operator, which allocates memory, runs constructors, etc. In your code sample, both StringBuilder and List<StringBuilder> are reference types.

The key aspect of managed languages that is important here is the automatic garbage collection. At runtime, the .NET Framework "knows" which objects you have created, because you're always creating them from it's own internally-managed heap (no direct malloc or anything like that in C#). It also "knows" when an object has gone completely out of scope -- when there are no more references to it anywhere in your program. Once that happens, the runtime is able to free the memory whenever it wants to, typically when it starts to run low on free memory, and you never have to do it. In fact, there is no way in C# to explicitly destroy a managed object (though you do have to clean up unmanaged resources if you use them).

In your example, the runtime knows that you've created a StringBuilder and put it into a List<>; it will keep track of that object, and as long as it's in the List<> it will stick around. Once you either remove it from the List<>, or the List<> itself goes away, the runtime will automatically clean up the StringBuilder for you.

Michael Edenfield
  • 28,070
  • 4
  • 86
  • 117
  • thanks, you made it for me clearer ! After coding c++, I become a lit bit suspecious ... I believe I have to read a book about C#. – icaptan Jul 23 '12 at 17:16