Thread: Strange error with class members

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    7

    Question Strange error with class members

    Hi. I have a very strange problem in my project that is the lost of values in some variables of some classes. I'm using MinGW that comes with CodeBlocks 10.0.5. I didn't post the code, because my code is very large and I believe that my problem can be more comprehensive if I only show code to ilustrate what is happening. In my project, I have a base class that contains many derived classes, like below:

    Code:
    class Base_Class{
    public:
    any functions
    A a;
    B b;
    C c...
    };
    The derived classes have a pointer to base class:

    Code:
    class A{
    public:
    any functions
    
    private:
    Base_Class* base_class;
    other private members
    };
    Sometimes, a variable of an derived class "loses" your value. Like below:

    Code:
    class A{
    public:
    void load_image();
    void display_image();
    void set_path_image( int new_path_image );
    int get_path_image();
    
    private:
    Base_Class* base_class;
    string path_image;
    };
    
    void A::load_image(){
    path_image = get_path_from_dialog();
    }
    
    void A::display_image(){
    show_image( path_image );
    }
    
    void A::set_path_image( int new_path_image ){
    path_image = new_path_image;
    }
    
    int A::get_path_image(){
    return path_image;
    }
    Inside of function load_image, path_image receive the correct value. But, when its exit of function, it loses this value. Then, in function display_image() your value aren't more correct. This happening with variables of other types, like vectors and strings, but not happening with all variables, only with some. My solution is build other class and insert the variable. But this is very awkward and makes the code confusing. This happening in other classes too, but in a lower frequency. Please, help me and sorry for my bad english.
    Last edited by lcecil; 04-26-2012 at 09:52 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by lcecil
    I have a base class that contains many derived classes, like below:
    This does not make sense to me, unless you are saying that the derived classes are not derived from Base_Class, in which case the fact that they are derived classes does not appear significant in this context. Furthermore, in your example, A is not derived from Base_Class.

    Post the smallest and simplest compilable program that demonstrates the problem.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    7
    Sorry. What I meant by "derivatives" are classes that belong to the class mentioned. For a moment I forgot the sense of inheritance that the word carries in oop. I have no other programs in which the problem appears. I will do another project, using similar logic to which I have employed in this and see if the error repeats. Thank you for your reply.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by lcecil
    What I meant by "derivatives" are classes that belong to the class mentioned.
    What you really mean are "member variables", "data members", "properties" or "attributes" of class type. "Classes that belong to the class" sound more like nested classes.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Apr 2012
    Posts
    7
    I made a program that follows the same logic that my project. However, the code not compiled. After the error, I compared the two programs to see if the simple program have the same logic that the my project have. I didn't see any difference. The code is below:

    main.cpp:

    Code:
    #include <class_a.h>
    #include <iostream>
    #include <deque>
    
    using namespace std;
    
    std::deque<A*> tests_objects;
    
    int main()
    {
    tests_objects.push_back( &A() );
    ( *( tests_objects.begin() ) )->b.set_test_variable_2( 2 );
    ( *( tests_objects.begin() ) )->b.get_test_variable().push_back( 5 );
    return 0;
    }
    class_a.cpp:

    Code:
    #include <class_a.h>
    
    //Description:This file contain the implementation of class A.
    
    //Name of class:A
    //Way to use:Declare a instance of this class in beginning of app, in main.cpp.
    
    A::A(){
    initialize_class_composed();
    }
    
    //Name of funcion:void A::initialize_class_composed()
    //Description:Initialize classes members of this class.
    //Way to use:This function might be called in constructor of this class.
    //Observations:None.
    void A::initialize_class_composed(){
    b.set_a( this );
    }
    class_a.h:

    Code:
    #ifndef CLASS_A_H_INCLUDED
    #define CLASS_A_H_INCLUDED
    
    #include <class_b.h>
    
    class A{
    public:
    A();
    void initialize_class_composed();
    B b;
    };
    
    #endif // CLASS_A_H_INCLUDED
    class_b.cpp:

    Code:
    #include <class_b.h>
    
    //Description:This file contain the implementation of class B.
    
    //Name of class:B
    //Way to use:Declare a instance in class A.
    
    B::B(){
    }
    
    std::deque<int>& B::get_test_variable(){
    return test_variable;
    }
    
    std::deque<int>::iterator& B::get_iterator_test_variable(){
    return iterator_test_variable;
    }
    
    void B::set_test_variable_2( int new_test_variable_2 ){
    test_variable_2 = new_test_variable_2;
    }
    
    int B::get_test_variable_2(){
    return test_variable_2;
    }
    
    void B::set_a( A* new_a ){
    a = new_a;
    }
    
    A* B::get_a(){
    return a;
    }
    class_b.h:

    Code:
    #ifndef CLASS_B_H_INCLUDED
    #define CLASS_B_H_INCLUDED
    
    #include <deque>
    
    class A;
    
    class B{
    public:
    B();
    std::deque<int>& get_test_variable();
    std::deque<int>::iterator& get_iterator_test_variable();
    void set_test_variable_2( int new_test_variable_2 );
    int get_test_variable_2();
    void set_a( A* new_a );
    A* get_a();
    
    private:
    A* a;
    std::deque<int> test_variable;
    std::deque<int>::iterator iterator_test_variable;
    int test_variable_2;
    };
    #endif // CLASS_B_H_INCLUDED
    All this is very strange. What I did in this program I did in my project several times without any crash occurred. What happened is that sometimes the data value was lost. But this didn't happen with all the data, only a few. This is even more curious. How can there be many of the same data type that will work and others that not work in the same class? If it is a error, should not be equal for all data? I don't understand. 

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Here's your code in one file so it's easier for someone to copy/paste/run. Note the small change in main to get it to compile.

    It seems to run. What exactly is the problem?

    Code:
    #include <iostream>
    #include <deque>
    
    class A;
    
    class B{
    public:
        B();
        std::deque<int>& get_test_variable();
        std::deque<int>::iterator& get_iterator_test_variable();
        void set_test_variable_2( int new_test_variable_2 );
        int get_test_variable_2();
        void set_a( A* new_a );
        A* get_a();
    
    private:
        A* a;
        std::deque<int> test_variable;
        std::deque<int>::iterator iterator_test_variable;
        int test_variable_2;
    };
    
    
    //Description:This file contain the implementation of class B.
    //Name of class:B
    //Way to use:Declare a instance in class A.
    
    B::B(){
    }
    
    std::deque<int>& B::get_test_variable(){
        return test_variable;
    }
    
    std::deque<int>::iterator& B::get_iterator_test_variable(){
        return iterator_test_variable;
    }
    
    void B::set_test_variable_2( int new_test_variable_2 ){
        test_variable_2 = new_test_variable_2;
    }
    
    int B::get_test_variable_2(){
        return test_variable_2;
    }
    
    void B::set_a( A* new_a ){
        a = new_a;
    }
    
    A* B::get_a(){
        return a;
    }
    
    
    class A{
    public:
        A();
        void initialize_class_composed();
        B b;
    };
    
    
    //Description:This file contain the implementation of class A.
    //Name of class:A
    //Way to use:Declare a instance of this class in beginning of app, in main.cpp.
    
    A::A(){
        initialize_class_composed();
    }
    
    //Name of funcion:void A::initialize_class_composed()
    //Description:Initialize classes members of this class.
    //Way to use:This function might be called in constructor of this class.
    //Observations:None.
    void A::initialize_class_composed(){
        b.set_a( this );
    }
    
    
    std::deque<A*> tests_objects;
    
    int main() {
        A a = A();
        tests_objects.push_back( &a );
        (*tests_objects.begin())->b.set_test_variable_2( 2 );
        (*tests_objects.begin())->b.get_test_variable().push_back( 5 );
        return 0;
    }
    Last edited by oogabooga; 04-27-2012 at 09:34 AM.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  7. #7
    Registered User
    Join Date
    Apr 2012
    Posts
    7
    The code with &a works.
    Why when I write &a instead of &A() it compiles? If I use only the test_variable_2, the program compiles. See this:

    Code:
    #include <class_a.h>
    #include <iostream>
    #include <deque>
    using namespace std;
    std::deque<A*> tests_objects;
    int main()
    {
        tests_objects.push_back( &A() );
        ( *( tests_objects.begin() ) )->b.set_test_variable_2( 2 );
        cout << ( *( tests_objects.begin() ) )->b.get_test_variable_2() << std::endl;
        return 0;
    }
    Works fine. Why it doesn't works for deque variable and works for int variable? If the problem is in the use of &A(), it should not crash for any variable?

  8. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Doing this
    x.push_back( &A() );
    creates a temporary variable of type A, which you then take the address of and store in the deque. But after that statement, the temporary A variable NO LONGER EXISTS, so dereferencing the address is undefined bahavior WHETHER OR NOT YOU GET A SEGFAULT. You will not always get a segfault.

    You need to set your compiler's warning level higher. Add -Wall to your compiler command line (assuming you're using gcc). Then you will be warned about such things.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  9. #9
    Registered User
    Join Date
    Apr 2012
    Posts
    7
    This assignment of the temporary variable includes other unexpecteds behaviours, like lost of value of some variables?Looking in my project( the real, not this small ) again, see that there are deques of variables, not deques of ponteirs of variables. Like below:
    Code:
    #include <class_a.h>
    #include <iostream>
    #include <deque>
    
    using namespace std;
    
    std::deque<A> tests_objects;
    
    int main()
    {
        tests_objects.push_back( A() );
        ( *( tests_objects.begin() ) ).b.set_test_variable_2( 2 );
        ( *( tests_objects.begin() ) ).b.get_test_variable().push_back( 5 );
        return 0;
    }
    In this case, may happen lost of value of some variable?

  10. #10
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Now you've changed the code. That code should work (assuming a proper copy constructor) since you are passing a copy of the A variable, not just its address.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  11. #11
    Registered User
    Join Date
    Apr 2012
    Posts
    7
    Without lose of value of variables? Because this last version is used in my project and happens lose of value of variables. I renember that in my project, the class B uses function get_a() to access the members of class A and even members of a class C, D, etc...

  12. #12
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    To reiterate what laserlight said earlier:
    "Post the smallest and simplest compilable program that demonstrates the problem."

    You still haven't done that since now you're saying that the example code you posted does NOT demonstrate the problem.

    Create some example code (in a single file) that demonstrates the REAL problem. If you can't do that then you need to make the entire code available.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  13. #13
    Registered User
    Join Date
    Apr 2012
    Posts
    7
    oogabooga, I don't can place all in a single file because now the class B and a new class, C, and other classes make reference to A. I don't know how make this in a single file, because B requires more than a foward declaration, requires the full implementation. But I can make this with include files.
    So, what compiler you uses? I have Visual Studio 2010 and CodeBlocks 10.0.5. I can make a project and put as an attachment. There will be many files.
    I'm creating a project to create code and these classes to simulate the various classes and variables of my project. These variables will be writed on a stream and when a value was incorret, "Error" will be written after the variable's value.

  14. #14
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    If those are my options, I'll choose CodeBlocks.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 08-12-2009, 04:46 AM
  2. Linking error with static template class members
    By cunnus88 in forum C++ Programming
    Replies: 6
    Last Post: 04-02-2009, 12:31 PM
  3. Strange bracket mismatch undefined class error
    By Shamino in forum C++ Programming
    Replies: 8
    Last Post: 11-19-2007, 11:36 AM
  4. Replies: 1
    Last Post: 12-11-2002, 10:31 PM
  5. iterators and class members
    By elad in forum C++ Programming
    Replies: 2
    Last Post: 03-18-2002, 06:39 PM