Thread: When is a c++ class deallocated if inserted vector but it goes out of scope

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    27

    When is a c++ class deallocated if inserted vector but it goes out of scope

    I need to know when a C++ class is deallocated if it's inserted into a vector but later goes out of scope because it exits from a function call.


    I have written a function called Tokenize that takes a tokens as a vector. Inside the function, I create a C++ class called TokenItem and it's inserted into a tokens vector using push_back function call.

    Code:
    void TokenManager::Tokenize(const string & str,	                   
    	                       vector<TokenItem>&tokens, string del) 
    ...
    //The TokenItem is created and inserted into a vector called tokens
    tokens.push_back( TokenItem(tokenStateInsert, 
    str.substr(lastPos, pos - lastPos)));      
    ...
    Question #1. Why isn't the TokenItem deallocated once it goes out of the function call? After all, I am able to access it using the following array access:
    Code:
    for (int x=0; x < sets.size(); x++) {
    	   TokenItem aToken= sets[x];
    ...
    Question #2 In the push_back function, I also used the str.substr call.
    That must create another copy of the string right? When is that string class deallocated?

  2. #2
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    I need to know when a C++ class is deallocated if it's inserted into a vector but later goes out of scope because it exits from a function call.
    AFAIK, If it is on the stack, it just vanishes...freeing the memory.
    else the vector's destructor(if you delete the vector) takes care of destroying everything.

    Question #2 In the push_back function, I also used the str.substr call.
    That must create another copy of the string right? When is that string class deallocated?
    Yes.
    When it goes out of scope.
    Last edited by manasij7479; 08-27-2011 at 04:30 PM.

  3. #3
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Quote Originally Posted by derder View Post
    Question #1. Why isn't the TokenItem deallocated once it goes out of the function call? After all, I am able to access it using the following array access:
    It is destroyed after the whole statement is executed. When you create your TokenItem class, you pass its reference to vector's push_back() which in turn stores a COPY of the object pointed by that reference. In your loop, you access that copy.

    Quote Originally Posted by derder View Post
    Question #2 In the push_back function, I also used the str.substr call.
    That must create another copy of the string right? When is that string class deallocated?
    Yes, this creates another string. This instance is also destroyed after the execution of the statement (but the object's constructor makes a copy of it, before it goes out of scope).

  4. #4
    Registered User
    Join Date
    Jul 2011
    Posts
    27
    Quote Originally Posted by kmdv View Post
    It is destroyed after the whole statement is executed. When you create your TokenItem class, you pass its reference to vector's push_back() which in turn stores a COPY of the object pointed by that reference. In your loop, you access that copy.



    Yes, this creates another string. This instance is also destroyed after the execution of the statement (but the object's constructor makes a copy of it, before it goes out of scope).
    Question #3 When a C++ copy is made, does it make a deep copy or shallow?
    I would all the primtivies such as int and anything can added to a stack is copied.
    How would an C++ object inside an object is copied?


    Question #4. So if that's the case, if I create a constructor
    Code:
    TokenItem(char, string &str) {
     token=str;
    }
    then the token=str assignment makes a copy right?

    Question #5.
    This is odd. While writing a test sample code for this post, the following code seems to compile. How would the program know what constructor to call?

    Code:
    TokenItem::TokenItem(char del, string tok) {
    	deliminator=del;
    	token=tok;	
    	
    }
    
    TokenItem::TokenItem(char del, string &tok) {
    	deliminator=del;
    	token=tok;	
    	
    }

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    3. If you don't specify the copy constructor, then a shallow copy is made. If you do specify the copy constructor, then that is used.

    4. That depends on what kind of thing token is. If token is a string, then yes a copy is made.

    5. Whichever matches the types of the things you call it with. If you call it with a char and a string, then the first. If you call it with a char and a string&, the second. As I recall the rules, the second won't get called unless the compiler really only has a reference (as in, say, a return from a function call) instead of an object.

  6. #6
    Registered User
    Join Date
    Jul 2011
    Posts
    27
    Quote Originally Posted by tabstop View Post

    5. Whichever matches the types of the things you call it with. If you call it with a char and a string, then the first. If you call it with a char and a string&, the second. As I recall the rules, the second won't get called unless the compiler really only has a reference (as in, say, a return from a function call) instead of an object.
    I am disgressing from my original subject in this post a bit, but I tried calling with string& and got a compiler error. Here's what I have delcared:
    Code:
    TokenItem::TokenItem(char del, string &tok) {
    	deliminator=del;
    	token=tok;	
    	
    }
    
    //However when I call with 
    tokens.push_back( TokenItem(tokenStateInsert, 
    &str.substr(lastPos, pos - lastPos)));      
    
    //or 
    tokens.push_back( TokenItem(tokenStateInsert, 
    str.substr(lastPos, pos - lastPos)&));
    I got compiler error.

  7. #7
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Code:
    TokenItem(tokenStateInsert,  &str.substr(lastPos, pos - lastPos))
    This creates an instance of TokenItem that isn't a lvalue.
    So, you can't pass it by reference.
    (I'm not completely clear about what the C++11 rvalue references are supposed to do.)

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Why are you putting a & in the call? You don't want the "address of" something.

    Anyway, I haven't tried the below (just typed it in this box here) but it might give you a better idea:
    Code:
    #include <iostream>
    #include <string>
    
    void function(std::string x) {
        std::cout << "In first function: " << x << std::endl;
    }
    
    void function(std::string& x) {
        std::cout << "In second function: " << x << std::endl;
    }
    
    int main(void) {
        std::string foo("Hello");
        function(foo);
        function(foo.insert(3, "ll"));
        function(foo.substr(0,2));
    }
    The idea being that foo.insert modifies foo and returns a reference to it, while foo.substr generates a whole new string object and returns that object.

    (EDIT: Now that I have actually tried it, it seems that was a bad example; as the two function calls were both errors for ambiguous overload (although it did report the type as std::string&) -- not sure why? I'll have to read more.)

    FURTHER EDIT: Okay, so I hadn't realized that the binding from string& to string was considered an identity; so I think you're right, the compiler will not be able to distinguish between them in most cases. If you only use one of the two, the first will handle all three function calls just fine, but the second (with the reference) will only handle the first two (the last is a temporary string object, and so the reference cannot bind to it. Whether this changes in C++11 I don't know).
    Last edited by tabstop; 08-28-2011 at 02:35 PM.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    R-value references can bind to temporary objects and this is really its purpose. It allows us to create temporary objects which we can then bind a reference to. The reason behind this is that so we can "steal" the temporary's resources, instead of allocating new resources and copying the data over.

    So if we have
    foo("foo");
    It will call foo(std::string&&)

    And if we have
    string boo("foo");
    foo(boo);
    It will call foo(std::string&)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer to vector, scope and Locals
    By Lagrange in forum C++ Programming
    Replies: 6
    Last Post: 02-18-2010, 03:29 AM
  2. Class Scope
    By strokebow in forum C++ Programming
    Replies: 7
    Last Post: 12-17-2008, 05:45 PM
  3. Vector of pointers and scope
    By krappa in forum C++ Programming
    Replies: 6
    Last Post: 11-22-2004, 02:10 PM
  4. Class scope variables
    By filler_bunny in forum C++ Programming
    Replies: 2
    Last Post: 08-23-2003, 02:14 AM
  5. class scope
    By Kohatian 3279 in forum C++ Programming
    Replies: 2
    Last Post: 03-19-2002, 01:28 PM