CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    May 2009
    Location
    Boston
    Posts
    364

    methods for declaring and populating an object in a loop

    Hello,

    I have a result object and a function that populates it. I am using an object for the results because the returned information is complex. The processing function is called many times in a loop, so each iteration need an un-populated object to work on. Once the populated object is returned, it is read and processed and can then be reused or go away. At the moment it looks something like this,

    Code:
    class result {
    
    public:
       // initialize class members
       result() : bool1(false), bool2(false), int1(0), int2(0) { }
    
       // each evaluated data member will receive one of these designations
       bool bool1, bool2;
    
       // these counts relate to the reasons for the above designations
       unsigned int int1, int2;
    
       // etc
    
    };
    
     // function to process data and populate result object
    void process_data(data& current_data, result& current_result) {
        // process current_data and set current_result member variables
    return;
    }
    
    // function to reset result object for next iteration
    void reinitialize_result_object(result& current_result) {
    
       // reset member variables
       current_result.bool1 = false;
       current_result.bool2 = false;
       current_result.int1 = 0;
       current_result.int2 = 0;
    
    return;
    }
    
    int main() {
    
       // result object
       result current_result;
    
       // loop through data
       for(unsigned int it=0, i<data.size(); i++) {
    
          // set next data member
          current_data = data[i];
    
          // process current data
          process_data(current_data, current_result);
    
          // process result object
    
          // reinitialize result object for next loop
          reinitialize_result_object(current_result);
    
       }
    
    return;
    }
    I have left out the specifications for the data and how the result object is processed. As you see, there is a function to clear the result object for the next loop. I guess it would be more c++ to have the clear function declared in the class. This is a bit old fashioned and I have looked at having the processing function return the result object like,

    Code:
    class result {
    
    public:
       // initialize class members
       result() : bool1(false), bool2(false), int1(0), int2(0) { }
    
       // each evaluated data member will receive one of these designations
       bool bool1, bool2;
    
       // these counts relate to the reasons for the above designations
       unsigned int int1, int2;
    
       // etc
    
    };
    
     // function to process data, populate, and return result object
    result process_data(data& current_data) {
    
       // result object
       result current_result;
    
        // process current_data and set current_result member variables
    
    return current_result;
    }
    
    int main() {
    
       // loop through data
       for(unsigned int it=0, i<data.size(); i++) {
    
          // set next data member
          current_data = data[i];
    
          // process current data
             result current_result = process_data(current_data);
    
          // process result object
    
       }
    
    return 0;
    }
    This second method does not need a function to clear the result object for each loop (I think). It seems as if the second method involves declaring/constructing a new object on every iteration of the loop and it's not clear to me what happens to the old object since nothing in main will go out of scope until it completes.

    What exactly happens in this second version of the code. Is the object simply overwritten with new data? Is a destructor of some kind called to get rid of it? Will I end up with thousands of unused objects floating in hyperspace? Is there any possible issue of a memory leak with this approach?

    At any rate, is one method preferred over the other, or is there some other method I haven't considered?

    Thanks for the advice?

    LMHmedchem
    Last edited by LMHmedchem; August 13th, 2018 at 12:41 PM.

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: methods for declaring and populating an object in a loop

    What version of c++ are you using? I seem to remember somewhere that you are using c++98?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: methods for declaring and populating an object in a loop

    In method 2, the scope of current_result is from its declaration to the end of the block in which it's declared. Its constructor is called on the line that declares it and it's destructor is called when it goes out of scope when it encounters the for }. Thus for each time around the for loop current_result is constructed, initialised, used and then destructed. So there's no "unused objects floating in hyperspace" and no memory leak assuming class result destructor is correct (and for 2 bools and 2 ints the default destructor is fine).

    Method 2 is the preferred way. Note that if result used dynamic memory then for c++98 method 1 would be preferable (as c++98 didn't use move semantics). Your class doesn't so this isn't an issue here now.

    Note
    Code:
    result process_data(data& current_data) {
    should be if possible
    Code:
    result process_data(const data& current_data) {
    and

    Code:
          current_data = data[i];
          result current_result = process_data(current_data);
    becomes
    Code:
             result current_result = process_data(data[i]);
    Note that if you're using at least a c++11 compiler, this becomes

    Code:
        for (const auto& current_data : data) {
             auto current_result = process_data(current_data);
            // process result
        }
    Last edited by 2kaud; August 13th, 2018 at 01:55 PM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    Join Date
    May 2009
    Location
    Boston
    Posts
    364

    Re: methods for declaring and populating an object in a loop

    Quote Originally Posted by 2kaud View Post
    What version of c++ are you using? I seem to remember somewhere that you are using c++98?
    I typically use c++98, but I do probably have other versions installed. I would probably have to change my makefile.

    The result class has about 12 bools and about the same number of ints, so there isn't any dynamic memory involved, just primitives. It seems like the first method is lighter weight in that only one object is constructed and the reinitialization is just done with a few assignments. What are the benefits of invoking both the constructor and destructor on each iteration of the loop. This could loop hundreds of thousands of times in theory.

    You mentioned cases where the default destructor may not be adequate. I generally assume that when a function returns, any objects that were in scope in the function will be nicely cleaned up. Are there cases where this is not true?

    Here is a class that uses objects of two other classes (vector_data, row_data) and at least one vector. Would a custom destructor be necessary for something like this? There really would be quite allot of information in one of these objects. There would probably be at least 20 vectors of double and a mess of other stuff.
    Code:
    class plane_set {
    
    public:
    
    // public access functions
    
    // member functions
    
       // initialize class members
       plane_set()
          : sum_EQ_2pi(false),
            ct_GT_90(0),
            ABC_CBD_angle(0.0),
            ABC_CBE_angle(0.0),
            DBC_CBE_angle(0.0),
            plane_intersection_sum(0.0) { }
    
       bool sum_EQ_2pi;
       unsigned int ct_GT_90;
       double ABC_CBD_angle, ABC_CBE_angle, DBC_CBE_angle;
       double plane_intersection_sum;
       std::vector<double> angle_BC_values;
       vector_data sum_vector, vector_BA, vector_BD, vector_BE, vector_AD, vector_AE;
       row_data point_B, point_A, point_D, point_E, point_C;
    
    };
    I always use const for any variable that is not modified in the function. I just forgot to add that in my pseudocode.

    LMHmedchem
    Last edited by LMHmedchem; August 13th, 2018 at 09:37 PM.

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: methods for declaring and populating an object in a loop

    You mentioned cases where the default destructor may not be adequate. I generally assume that when a function returns, any objects that were in scope in the function will be nicely cleaned up. Are there cases where this is not true?
    When the object class explicitly uses dynamic memory (new/malloc etc) and the destructor doesn't delete (delete/delete []/free etc) the allocated memory properly.

    Would a custom destructor be necessary for something like this?
    No - as dynamic memory is not explicitly used. What type is vector_data and row_data?

    As class result doesn't use any dynamic memory (either explicitly or implied) and hence its data is purely stack based, the constructor only initialises the data - which reinitialize_result_object() would do - so there is no performance penalty here. The destructor does nothing so again there is no performance penalty.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

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