Thread: Vector Problem

  1. #1
    Yah. Morgul's Avatar
    Join Date
    Feb 2005
    Posts
    109

    Vector Problem

    I'm in the process of doing some game work with vectors and have come upon an unexpected problem. When I try to add new items to the vectors, my program complains and fails to run. The MSVC++ 2005 EE debugger points me towards an error caused by the vector size() function.

    Code:
    size_type size() const
    {	// return length of sequence
         return (_Myfirst == 0 ? 0 : _Mylast - _Myfirst);
    }
    Specifically, it tells me that the return statement caused the error (kinda obvious since that is the only statement in there). I am not calling the size() function and though I'm relatively new to using vectors I'm thinking (correct me if I'm wrong) that when I call push_back() to add an item to the vector it probably internally calls the size() function.

    Code pretaining to my use of vectors (I'm using the std namespace which is why I'm not using std::, I didn't think that had a great effect on anything):

    I initialize it here
    Code:
    vector<Mesh *> MeshList;
    Then here is where I try to add an item to the vector.
    Code:
    MeshList.push_back(TempMesh);
    TempMesh is a filled in Mesh structure initialized thus:
    Code:
    Mesh *TempMesh = new Mesh();
    And filled in accordingly afterwards.


    Specifically, the debugger tells me:
    Unhandled exception at 0x00412be6 in Direct3D Test.exe: 0xC0000005: Access violation reading location 0x00000008.
    Though that probably isn't much help to anything.


    Do I need to initialize the vector different? Is it mad that I'm not putting anything at all in it?
    Sic vis pacum para bellum. If you want peace, prepare for war.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    um....ok


    Code:
    DWORD GetSize()
    {
      return vVector.size();
    }
    size() returns the length of the controlled sequence.

  3. #3
    Yah. Morgul's Avatar
    Join Date
    Feb 2005
    Posts
    109
    Sorry, I guess I wasn't that clear. When I try to add items to a vector, the application crashes and tells me there was an unhandled exception when calling the size() function, and there is no reason for it to do that.

    That size function I gave was the actual size function in the vector class.
    Sic vis pacum para bellum. If you want peace, prepare for war.

  4. #4
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    It looks like your vector isn't being created. Is this code within the method of a class? If so, make sure the object whos method your calling is indeed being created.

    If not, try calling MeshList.Reserver(10) before push_back(). I don't expect that to fix it though.

  5. #5
    Yah. Morgul's Avatar
    Join Date
    Feb 2005
    Posts
    109
    This code is within a class (the vector being initialized in the class, and then the rest is in a function).

    I tried MeshList.Reserve(10), and am being given an unhandled exception in the capacity() vector function. This leads me to believe that the vector is, like you suggested, not being initialized properly. I checked, and the object is being created - there seems to be another problem.
    Sic vis pacum para bellum. If you want peace, prepare for war.

  6. #6
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    Code:
    vector<Mesh *> * memAddress = &MeshList;
    If you throw that line before push_back(), what's the value of memAddress?

  7. #7
    Yah. Morgul's Avatar
    Join Date
    Feb 2005
    Posts
    109
    It has a non null value, however otherwise I'm not exactly sure how you'd like me to check the value of a pointer to a vector, since the vector should be empty.
    Sic vis pacum para bellum. If you want peace, prepare for war.

  8. #8
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    The vector should be empty, but the pointer to the created vector object should not be, which it isn't. Try posting this in the C++ forum if you already haven't, since this isn't a game specific problem.

    edit: That's my way of saying "I don't know what's wrong, and it seems like nobody else does either."

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Using vectors is simple.

    Code:
    class CObject 
    {
    };
    
    
    class CObjectContainer
    {
      //Vector of pointers to CObject's
      std::vector<CObject *> Objects;
    
      public:
        virtual ~CObjectContainer(void)
        {
           for (DWORD i=0;i<Objects.size();i++)
           {
              if (Objects[i]) delete Objects[i];
           }
    
           Objects.clear();
        }
     
        void Add(CObject *ptrObject)
        {
           Objects.push_back(ptrObject);
        }
    
        CObject *GetObject(DWORD dwIndex)
        {
          if (dwIndex<Objects.size())
          {
             return Objects[i];
          } else return NULL;
        }
    };
    I don't know what else to say here w/o more concrete examples of what is happening.

  10. #10
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Bubba
    I don't know what else to say here w/o more concrete examples of what is happening.
    Exactly, it's impossible to say what's wrong without some (more) code.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  11. #11
    Yah. Morgul's Avatar
    Join Date
    Feb 2005
    Posts
    109
    I will post it in the C++ specific board tomorrow, originally I planned to ask something more game specific but I changed it and never changed boards.

    I know using vectors should be simple and yet it is giving me a ton of trouble. I'm not quite sure what other code could possibly be helpful but I'll try anyway.

    Here is the code for the entire function where I fill out TempMesh and add it to the vector (MESH_TEAPOT is predefined elsewhere).
    Code:
    int MeshContainer::LoadMesh(IDirect3DDevice9* &g_pd3dDevice, int iMeshNum) {
    	Mesh *TempMesh = new Mesh();
    	switch(iMeshNum) {
    		case MESH_TEAPOT: // Create a Teapot
    			if(FAILED(D3DXCreateTeapot(g_pd3dDevice, &TempMesh->MeshData, 0)))
    				return false;
    			TempMesh->dwNumSubsets = 0;
    			TempMesh->dwID = 0;
    			break;
    		default:
    			return false;
    			break;
    	}
    	vector<Mesh *> * memAddress = &MeshList;
    	if(memAddress == NULL)
    		MessageBox(NULL, "memAddress == NULL", "Error!", MB_ICONSTOP | MB_OK);
    	MeshList.push_back(TempMesh);
    	if(TempMesh->MeshData != NULL) {
    		TempMesh->MeshData->Release();
    		TempMesh->MeshData = NULL;
    	}
    	delete TempMesh;
    	return true;
    }
    Here is the Mesh structure (I haven't finished it becuause I haven't been able to get the vector thing to work):
    Code:
    struct Mesh {
    	DWORD dwID;
    	DWORD dwNumSubsets;
    	LPD3DXMESH MeshData;
    	Mesh() {
    		dwID = 0;
    		dwNumSubsets = 0;
    		MeshData = NULL;
    	}
    };
    And here is the MeshContainer class (it is partially inspired from some of your ideas on research management Bubba and I haven't added much to it at all):
    Code:
    class MeshContainer {
    private:
    	vector<Mesh *> MeshList;
    public:
    	MeshContainer() {}
    	~MeshContainer() {
    		if(MeshList.size() > 0) {
    			for(DWORD i=0; i<MeshList.size(); i++) {
    				if(MeshList[i] != NULL) {
    					MeshList[i]->MeshData->Release();
    					MeshList[i] = NULL;
    				}
    			}
    			MeshList.clear();
    		}
    	}
    	void DrawMesh(DWORD dwMeshID);
    	int LoadMesh(IDirect3DDevice9* &g_pd3dDevice, int iMeshNum);
    };
    Sic vis pacum para bellum. If you want peace, prepare for war.

  12. #12
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    You shouldn't delete tempmesh in the function and you shouldn't call release on the meshdata either. This is because your MeshList holds pointers to Mesh objects, meaning that if the objects you push_back go out of scope/get destroyed, the list holds an invalid pointer. Instead, you should do memory deallocation only in the destructor or when you remove an element from the list.

    Edit: I also don't see any reason to have that memAddress variable/null check
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  13. #13
    Yah. Morgul's Avatar
    Join Date
    Feb 2005
    Posts
    109
    Yah, I never caught that stupid error becuase the program never gets to execute that line. I get the unhandled exception on the the push back function, and the program either crashes or if I'm in debug mode it breaks.

    That check isn't necessary and was from a request above. I did not delete it to show I put it in.
    Sic vis pacum para bellum. If you want peace, prepare for war.

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    vector<Mesh *> * memAddress = &MeshList;
    ??
    Why this?
    ??

  15. #15
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    Quote:
    vector<Mesh *> * memAddress = &MeshList;
    Why this?
    By looking at the memory address, you can find if MeshList was created at this point. Morgul had said it isn't null, which still does not mean it's been successfully created. But based on his error, I was expecting it to be null.

Popular pages Recent additions subscribe to a feed