CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Oct 2011
    Posts
    5

    Array Assignment and Memory Management

    Hi Guys,

    I was wondering if someone could tell me if assigning one array to another would cause memory problems.

    For Example

    Code:
    char[] largeFile = new char[5000000];
    
    public void method()
    {
          ObjectX objX = new ObjectX();
          objx.file = largeFile;
          largeFile = objx.file;
    }

    Does this mean that when method() is finished objX will not be collected by the GC or will it be? does file hold some reference to objx since it was assigned the objx.file even though objX would be out of scope after the method is done?
    Last edited by TheBean; October 9th, 2013 at 04:40 AM.

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Array Assignment and Memory Management

    What is the scope of file?

  3. #3
    Join Date
    Oct 2011
    Posts
    5

    Re: Array Assignment and Memory Management

    Sorry I screwed up, I have edited my op.

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Array Assignment and Memory Management

    I believe ObjX will be GC'd, but to be sure you might want to create a test app (and artificially make the ObjX consume a lot of memory) and then profile it using the VS profiler.

  5. #5
    Join Date
    Oct 2011
    Posts
    5

    Re: Array Assignment and Memory Management

    Thanks for your reply I have another simular question.



    Code:
    public class ObjectX
    {
        public List<char> myFile;
    
        ...
    ....
    ..
    
    }
    
    
    And then in lets say Form1.cs
    
    I had
    
    Public Class Form1
    {
         List<char> myFile;
         ObjectX obx = new ObjectX();
         private void initializeComponents()
         {
              //open large text file into myFile
              StreamReader sr = new StreamReader("path/to/file/large.txt);
              char[] tmpFile = new char[500000]
              sr.Read(tmpFile, 0, tmpFile.Length);
              myFile = new List<char>(tmpFile);
              objx.myfile = myFile;
          }
    }

    Then does this mean that objX.myfile is a reference to form1.myFile and therefore would not consume any more Ram?

    Lets say if in ObjectX there was a method that added some more text to myFile with the List.Add function would this add them to both or would it create a new instance of it in memory.

    Sorry for the basic question here but I am trying to further my understanding of how this works.

    Also the code above is just what i typed here to get my point across.

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Array Assignment and Memory Management

    Honestly, I'm not up on the exact specifics here. When I design a new class that needs to free up resources, I always implement IDisposable on the class and use a using block. Inside the Dispose(bool isDisposing) method, I can control what gets cleaned up.

    To modify your example somewhat:
    Code:
    public Class Form1
    {
      List<char> myFile;
      
      private void initializeComponents()
      {
        using(var obx = new ObjectX())  // ObjectX implements IDisposable
        {
          //open large text file into myFile
          var sr = new StreamReader("path/to/file/large.txt");
          var tmpFile = new char[500000]
          
          sr.Read(tmpFile, 0, tmpFile.Length);
          myFile = new List<char>(tmpFile);
          objx.myfile = myFile;
        } // resources within ObjectX get cleaned up here
      }
    }

  7. #7
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Array Assignment and Memory Management

    Quote Originally Posted by TheBean View Post
    Hi Guys,

    I was wondering if someone could tell me if assigning one array to another would cause memory problems.

    For Example

    Code:
    char[] largeFile = new char[5000000];
    
    public void method()
    {
          ObjectX objX = new ObjectX();
          objx.file = largeFile;
          largeFile = objx.file;
    }

    Does this mean that when method() is finished objX will not be collected by the GC or will it be? does file hold some reference to objx since it was assigned the objx.file even though objX would be out of scope after the method is done?
    Arrays are reference types (like classes); this essentially means that largeFile is, conceptually, a pointer to the actual array (whatever the actual implementation is "under the hood"), except that you cant directly manipulate the pointer itself as you can, say, in C++.

    Now, assuming the type of ObjectX.file field/property is char[], and that it simply takes the assigned value as is, after the line

    objx.file = largeFile;

    file refers to the exact same array instance - its just another "pointer" (in C# jargon, another reference) to the same array. Like, another label, or alias, for the same thing.

    Thus, the next line

    largeFile = objx.file

    simply reassigns largeFile back to itself, that is, it effectively does nothing.
    Even if that wasn't the case, the largeFile variable would simply be made to point to another array that was stored in (or rather, referenced by) objx.file. largeFile would have no knowlege of (a.k.a. no reference to) objx. How could it?
    So after the function exits, objx instance is free to be garbage collected, as it is not used anywhere else in the code - but this doesn't mean that the GC will release the char array as well, as there is a reference to that array held by the largeFile variable.

    Quote Originally Posted by TheBean View Post
    Thanks for your reply I have another simular question.



    Code:
    public class ObjectX
    {
        public List<char> myFile;
    
        ...
    ....
    ..
    
    }
    
    
    And then in lets say Form1.cs
    
    I had
    
    Public Class Form1
    {
         List<char> myFile;
         ObjectX obx = new ObjectX();
         private void initializeComponents()
         {
              //open large text file into myFile
              StreamReader sr = new StreamReader("path/to/file/large.txt);
              char[] tmpFile = new char[500000]
              sr.Read(tmpFile, 0, tmpFile.Length);
              myFile = new List<char>(tmpFile);
              objx.myfile = myFile;
          }
    }

    Then does this mean that objX.myfile is a reference to form1.myFile and therefore would not consume any more Ram?

    Lets say if in ObjectX there was a method that added some more text to myFile with the List.Add function would this add them to both or would it create a new instance of it in memory.

    Sorry for the basic question here but I am trying to further my understanding of how this works.

    Also the code above is just what i typed here to get my point across.
    Yes, Form1.myFile and objx.myfile would point to the same List<char> instance. One copy in memory. Any changes to the list's structure would be visible to both (and the list will not be garbage collected as long as it is somehow reachable from your running code).

  8. #8
    Join Date
    Jan 2010
    Posts
    1,133

    Re: Array Assignment and Memory Management

    BTW, to make a copy of a list, you must do it explicitly (or in general, for other data structures, use a method that does it, if one is provided - but make sure to read the docs to know how deep the copy will be).

    Now, take note here: if you make a copy of a list (or an array) of mutable reference type objects, there will be two different lists in memory, but all their members will be (distinct) references to one set of objects (the corresponding entries in each list will refer to the same object).
    This means that if you change the objects themselves, the changes will be visible via both of the lists. It's like a list of C++ pointers.

    However, if you change the structure of one list (add, or delete elements, or completely replace some elements with different ones (equivalent to making a pointer point to a different object)), these changes will be made to only one of the two lists (since there are two different lists in memory).

    Finally, if you instead had a list of value types (structs, and all fundamental types except for string), and made a copy of that list, the elements themselves would also be copied, because they are value type objects (and are thus passed around by value), so the two lists would be completely unrelated.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured