Thread: Copying memory, pointers and the like.

  1. #16
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by dwks
    Why don't you try something like this?
    Code:
    class CLASS_1{
        public:
        DataClass *data;
    
        CLASS_1(){
            data = NULL;
        }
        ~CLASS_1(){
            delete data;
            data = NULL;
        }
    };
    
    class CLASS_2{
        public:
        DataClass *data;
        CLASS_1 *class1;
    
        CLASS_2(){
            this->data = new DataClass();
    
            class1 = new CLASS_1();
            class1->data = this->data;
        }
        ~CLASS_2(){
            delete data;
            data = NULL;
    
            delete class1;
            class1 = NULL;
        }
    };
    This first example still yields undefined behaviour, because it has the problem of deleting something twice as, at the start of the CLASS_2 destructor, data and class1->data point at the same thing.
    Quote Originally Posted by dwks
    If you leave that line unchanged and allocate a new DataClass in CLASS_1's constructor, then use it instead of allocating a new one in CLASS_2's constructor.
    Code:
    class CLASS_1{
        public:
        DataClass *data;
    
        CLASS_1(){
            data = new DataClass();
        }
        ~CLASS_1(){
            delete data;
            data = NULL;
        }
    };
    
    class CLASS_2{
        public:
        DataClass *data;
        CLASS_1 *class1;
    
        CLASS_2(){
            this->data = new DataClass();
    
            //class1 = new CLASS_1();
            this->data = class1->data;
        }
        ~CLASS_2(){
            delete data;
            data = NULL;
    
            delete class1;
            class1 = NULL;
        }
    };
    In short, to fix your problem, you have to allocate only one DataClass.
    This example introduces another problem as, within CLASS_2's constructor, class1 is an uninitialised pointer (it is never initialised). So assigning this->data = class1->data yields undefined behaviour.

  2. #17
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Ok, thanks for the help everyone.

    I can't seem to figure out what causes the error when using one instance (as opposed to copying all the data). I've eliminated multithreading and any possible issues with using std::vector in this. For now I guess I'll just make copies of the data, since it doesn't seem to increase the overall memory footprint that much anyway.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  3. #18
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> data->subclass->vector[data->var].function(); //ERROR
    On that line, what is data->subclass->vector.size() and what is data->var?

  4. #19
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    size() = 1. data->var is always set to 0 (at least for testing purposes).
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  5. #20
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    How do you know size is 1, do you output it, check it in the debugger, or do you just know it should be 1?

    What does the data variable look like in the debugger's watch? Is its memory address 0x00000000, 0xcdcdcdcd, 0xdeadbeef, or something like that?

  6. #21
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    I wrote the size to my applications log file.

    These are the access violations the debugger gives me:
    Quote Originally Posted by VC++ 2005 Express
    First-chance exception at 0x00000000 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    A first chance exception of type 'System.AccessViolationException' occurred in Clockwork.exe
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    First-chance exception at 0x79eea7c3 in Clockwork.exe: 0xC0000005: Access violation reading location 0x00000000.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  7. #22
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    There are too many operations on the single line
    data->subclass->vector[data->var].function(); //ERROR
    Try to rewrite it in several operations with asserts inbetween
    Code:
    assert(data);
    SUBCLASS* ptr = data->subclass;
    assert(ptr);
    ITEM item = ptr->vector[data->var];
    item.function();
    and see where the ERROR occured exactly...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #23
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    I'm pretty sure the error would have to be occuring in function. data->subclass->vector contains vectors of other classes. function creates a new object in one of those vectors owned by vector. Looking through more debug info, the index of the child vector being set is NULL (0x000...more zero's). That would be causing the access violation. But I still can't seem to figure out why it ends up as NULL, only when pointing to the data class rather than copying it.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  9. #24
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    You'd better show us your DataClass, if possible. As much of it as is needed to demonstrate your problem.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  10. #25
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Well, I can't give all of the exact code (there's too much). But I can give a recreation of the problem causing code.

    Code:
    class DataClass{
        public:
        int var;
        SubClass *subclass;
    
        DataClass(){
            subclass = new SubClass();
        }
        ~DataClass(){
            delete subclass;
            subclass = NULL;
        }
    };
    
    class SubClass{
        public:
        int numVectors;
        std::vector<VectorClass> vector;
    
        SubClass(){
            numVectors = 0;
        }
    
        void newVector(){
            vector.reserve(numVectors+1);
            vector.push_back(VectorClass());
            numVectors++;
        }
    };
    
    class VectorClass{
        public:
        int numOtherVector;
        std::vector<OtherVectorClass*> otherVector;
    
        VectorClass(){
            numOtherVector = 0;
        }
    
        void AddToVector(){ //this is the function that causes the error
            otherVector.resize(numOtherVector+1);
            otherVector[numOtherVector] = new OtherVectorClass();
    
            numOtherVector++;
    
            /*otherVector appears to be NULL in the debugger*/
        }
    };
    And with that code, I would call:
    Code:
    data->subclass->newVector();
    
    /*other irrelevent code and stuff*/
    
    data->subclass->vector[data->var].AddToVector(); //data->var equals 0
    Last edited by psychopath; 12-10-2006 at 02:34 PM.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  11. #26
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> /*otherVector appears to be NULL in the debugger*/
    If otherVector is null there, then that means the VectorClass object is bad. Which means either data->subclass->vector[data->var], data->subclass, or data is bad. Try vart's suggestion and separate it out, checking each pointer to verify that it is valid.

  12. #27
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Look at this line:
    Code:
    std::vector<OtherVectorClass*> otherVector;
    If OtherVectorClass inherits from other classes (which may also inherit from other classes), how to I go about figuring out which class is causing the problems. Or would it have to be the top-level class that I make the pointer to (in this case, OtherVectorClass)?
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  13. #28
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    What IDE do you use?

    It shouldn't be about which derived class causes the problem. If the pointer inside the vector is null, then there is no derived class, because the pointer points at nothing.

    Did you try vart's suggestion? Which is the first pointer that is bad?

  14. #29
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    I'm using Visual C++ 2005 Express.

    I tried calling assert() after each class is created, although it didn't seem to do anything. In the debugger, otherVector[0] is NULL, meaning it's the bad pointer (I guess). otherVector[0] would be created after calling AddToVector().
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  15. #30
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I tried calling assert() after each class is created
    What about in that line of code? Look at data in the watch window. If it looks valid, then expand (*data).subclass and look at that. Visual Studio has an excellent debugger, you should be able to find lots of information.

    Since otherVector is an object, not a pointer in the code you posted, it would only make sense that the instance of the class that contains it is bad. That is why we are asking about the other things. The crash usually shows up somewhere other than where it is actually being caused. Move down the call stack and dig around looking at each variable to see which variable is the highest level one that is not valid. Only when you find out which pointer is bad should you then figure out why it is bad.

Popular pages Recent additions subscribe to a feed