Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 899
  • Last Modified:

Vector of Objects getting Uninitilized Memory error in my debug tool, Rational Purify

Hi Expert,
I have a COM DLL that I'm working on using VS2005 with only the windows library.  In this, I have declare a vector to store objects that are created based on my own class.  I've also coded the copy constructor and the Operator = overload so the vector would accept it.  Each field of each object that req mem allocation has memory allocated for it before I call the vector.Push_back. I'm getting Uninitilized Memory error in my debug tool, Rational Purify.  If I'm just run Active Directory, client of my COM, my dll would crash with unhandled win32 error.  I'm stuck here becuase I can't debug any further until I can resolve this bug.  

I've listed some code and the error message below.  Can you tell me what I'm missing here?  Thank you.

      vector <CUserContextData*> userDataObjects;
      vector <CUserContextData*>::iterator userDataIter;

      CUserContextData *newUserData = new CUserContextData;
...allocated memory and assign values to the member data fields.
            userDataObjects.push_back(newUserData);


class CUserContextData
{
public:
            
    bool newObject, bWinLogOn, bUnifiedID, symarkEnabled, UIDChanged;
    wchar_t *shell, *homeDir, *primaryGroup, *symarkUserRef, *LoginName,
*contextName;
       LPCWSTR lpcwContextName;
    int symarkUID, listViewIndex, UID;

      void CUserContextData::Copier(const CUserContextData &newUserData)
      {
            LPCWSTR lpcTemp;

            newObject = newUserData.newObject;
            bWinLogOn = newUserData.bWinLogOn;
            bUnifiedID = newUserData.bUnifiedID;
            symarkEnabled = newUserData.symarkEnabled;
            UIDChanged = newUserData.UIDChanged;
            symarkUID = newUserData.symarkUID;
            listViewIndex = newUserData.listViewIndex;
            UID = newUserData.UID;
             
            wchar_t *temp = new wchar_t[wcslen(newUserData.lpcwContextName)+1];
            wcscpy(temp, newUserData.lpcwContextName);
            lpcwContextName = T2CW(temp);
            delete [] temp;

            lpcTemp = T2CW(newUserData.contextName);
            contextName = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy(contextName, (lpcTemp));

            lpcTemp = T2CW(newUserData.LoginName);
            LoginName = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy(LoginName, (lpcTemp));
            
            lpcTemp = T2CW(newUserData.shell);
            shell = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy(shell, (lpcTemp));

            lpcTemp = T2CW(newUserData.homeDir);
            homeDir = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy(homeDir, (lpcTemp));

            lpcTemp = T2CW(newUserData.primaryGroup);
            primaryGroup = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy(primaryGroup, (lpcTemp));

            lpcTemp = T2CW(newUserData.symarkUserRef);
            symarkUserRef = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy(symarkUserRef, (lpcTemp));
}

      CUserContextData& CUserContextData::operator=(const CUserContextData&
newUserData)
      {
            if(this != &newUserData)
            {
                  delete [] shell;
                  delete [] homeDir;
                  delete [] primaryGroup;
                  delete [] symarkUserRef;
                  delete [] LoginName;
                  delete [] contextName;
                  delete [] lpcwContextName;

                  Copier(newUserData);
            }
            return *this;
}

      CUserContextData(void)
      {
            contextName = NULL;
            shell = NULL;
            homeDir = NULL;
            primaryGroup = NULL;
            symarkUserRef = NULL;
            LoginName = NULL;
            lpcwContextName = NULL;

      }

      CUserContextData::CUserContextData(const CUserContextData &newUserData)
      {
            Copier(newUserData);
            
      }
      virtual ~CUserContextData(void)
      {
                  //delete [] shell;
                  //delete [] homeDir;
                  //delete [] primaryGroup;
                  //delete [] symarkUserRef;
                  //if(LoginName != NULL)
                  //      delete [] LoginName;
                  //delete [] contextName;
                  //delete [] lpcwContextName;

      }

};



Error:
[W] UMR: Uninitialized memory read in
?_Debug_range@PAPAVCUserContextData@@@std@@YAXPAPAVCUserContextData@@0PB_WI@Z
{1 occurrence}
    Reading 1 byte from 0x0809e7ef (1 byte at 0x0809e7ef uninitialized)
    Address 0x0809e7ef points into a thread's stack
                    _Umove(_VEC_ITER_BASE(_Where), _Mylast, _Ptr);    //
copy suffix
                    _CATCH_ALL
    std::vector<CUserContextData *,allocator<CUserContextData
*>::std>::insert(_Vector_iterator<CUserContextData
*,allocator<CUserContextData *>::std>::std,CUserContextData * const const&)
[g:\program files\microsoft visual studio 8\vc\include\vector.:854]
            iterator insert(iterator _Where, const _Ty& _Val)
                {    // insert _Val at _Where
                size_type _Off = size() == 0 ? 0 : _Where - begin();
     =>         _Insert_n(_Where, (size_type)1, _Val);
                return (begin() + _Off);
                }
       
    std::vector<CUserContextData *,allocator<CUserContextData
*>::std>::push_back(CUserContextData * const const&) [g:\program
files\microsoft visual studio 8\vc\include\vector.:800]
         #endif /* _HAS_ITERATOR_DEBUGGING */
       
                else
     =>             insert(end(), _Val);
                }
       
         #if _HAS_ITERATOR_DEBUGGING
    CUserPage::RetrieveUserAtt(int,int,struct HWND__ *,wchar_t *)
[c:\projects\unityextproperty\cuserpage.cpp:554]
                    }
       
       
     =>         userDataObjects.push_back(newUserData);
                //Retrieve record and fill the Dialog screen and select the
item
                if( count == 0)
                {

   
?_Uninit_move@PAPAVCUserContextData@@PAPAV1@V?$allocator@PAVCUserContextData@@@std@@U_Undefined_move_tag@3@@std@@YAPAPAVCUserContextData@@PAPAV1@00AAV?$allocator@PAVCUserContextData@@@0@U_Undefined_move_tag@0@U_Range_checked_iterator_tag@0@@Z [g:\program files\microsoft visual studio 8\vc\include\memory.:160]
            _FwdIt _Uninit_move(_InIt _First, _InIt _Last, _FwdIt _Dest,
                _Alloc& _Al, _MoveCatTy, _Range_checked_iterator_tag)
            {    // move defaults to copy if there is not a more effecient way
     =>     return _STDEXT unchecked_uninitialized_copy(_First, _Last,
_Dest, _Al);
            }
       
        template<class _InIt, class _FwdIt, class _Alloc>
   
?_Unchecked_uninitialized_move@PAPAVCUserContextData@@PAPAV1@V?$allocator@PAVCUserContextData@@@std@@@stdext@@YAPAPAVCUserContextData@@PAPAV1@00AAV?$allocator@PAVCUserContextData@@@std@@@Z
[g:\program files\microsoft visual studio 8\vc\include\memory.:694]
                _Alloc& _Al)
            {    // move [_First, _Last) to raw _Dest, using _Al
                return (_STD _Uninit_move(_CHECKED_BASE(_First),
_CHECKED_BASE(_Last), _Dest, _Al,
     =>             _STD _Move_cat(_Dest), _STD
_Range_checked_iterator_tag()));
            }
       
        template<class _InIt,
   
?_Umove@PAPAVCUserContextData@@@?$vector@PAVCUserContextData@@V?$allocator@PAVCUserContextData@@@std@@@std@@IAEPAPAVCUserContextData@@PAPAV2@00@Z
[g:\program files\microsoft visual studio 8\vc\include\vector.:1112]
                pointer _Umove(_Iter _First, _Iter _Last, pointer _Ptr)
                {    // move initializing [_First, _Last), using allocator
                return (_STDEXT _Unchecked_uninitialized_move(_First, _Last,
     =>             _Ptr, this->_Alval));
                }
       
            void _Insert_n(iterator _Where,
    std::vector<CUserContextData *,allocator<CUserContextData
*>::std>::_Insert_n(_Vector_iterator<CUserContextData
*,allocator<CUserContextData *>::std>::std,UINT,CUserContextData * const
const&) [g:\program files\microsoft visual studio 8\vc\include\vector.:1143]
       
                    _TRY_BEGIN
                    _Ptr = _Umove(_Myfirst, _VEC_ITER_BASE(_Where),
     =>                 _Newvec);    // copy prefix
                    _Ptr = _Ufill(_Ptr, _Count, _Tmp);    // add new stuff
                    _Umove(_VEC_ITER_BASE(_Where), _Mylast, _Ptr);    //
copy suffix
                    _CATCH_ALL

    Address 0x0809e7ef is 33 bytes above the frame pointer in
?_Debug_range@PAPAVCUserContextData@@@std@@YAXPAPAVCUserContextData@@0PB_WI@Z
    Thread ID: 0xc8c
    Error location
   
?_Debug_range@PAPAVCUserContextData@@@std@@YAXPAPAVCUserContextData@@0PB_WI@Z
[g:\program files\microsoft visual studio 8\vc\include\xutility.:1368]
    template<class _InIt> inline
        void __CLRCALL_OR_CDECL _Debug_range(_InIt _First, _InIt _Last,
const wchar_t *_File, unsigned int _Line)
        {    // test iterator pair for valid range
 =>     _Debug_range2(_First, _Last, _File, _Line, _Iter_cat(_First));
        }
   
            // TEMPLATE FUNCTION _Debug_order
   
?_Uninit_copy@PAPAVCUserContextData@@PAPAV1@V?$allocator@PAVCUserContextData@@@std@@@std@@YAPAPAVCUserContextData@@PAPAV1@00AAV?$allocator@PAVCUserContextData@@@0@U_Scalar_ptr_iterator_tag@0@U_Range_checked_iterator_tag@0@@Z
[g:\program files\microsoft visual studio 8\vc\include\memory.:124]
        _FwdIt _Uninit_copy(_InIt _First, _InIt _Last, _FwdIt _Dest,
            _Alloc&, _Scalar_ptr_iterator_tag, _Range_checked_iterator_tag)
        {    // copy [_First, _Last) to raw _Dest, scalar type
 =>     _DEBUG_RANGE(_First, _Last);
        _DEBUG_POINTER(_Dest);
        size_t _Count = (size_t)(_Last - _First);
        _FwdIt _Result = _Dest + _Count;
   
?unchecked_uninitialized_copy@PAPAVCUserContextData@@PAPAV1@V?$allocator@PAVCUserContextData@@@std@@@stdext@@YAPAPAVCUserContextData@@PAPAV1@00AAV?$allocator@PAVCUserContextData@@@std@@@Z
[g:\program files\microsoft visual studio 8\vc\include\memory.:674]
            _Alloc& _Al)
        {    // copy [_First, _Last) to raw _Dest, using _Al
            return (_STD _Uninit_copy(_CHECKED_BASE(_First),
_CHECKED_BASE(_Last), _Dest, _Al,
     =>             _STD _Ptr_cat(_First, _Dest), _STD
_Range_checked_iterator_tag()));
            }
       
        template<class _InIt,
   
?_Uninit_move@PAPAVCUserContextData@@PAPAV1@V?$allocator@PAVCUserContextData@@@std@@U_Undefined_move_tag@3@@std@@YAPAPAVCUserContextData@@PAPAV1@00AAV?$allocator@PAVCUserContextData@@@0@U_Undefined_move_tag@0@U_Range_checked_iterator_tag@0@@Z [g:\program files\microsoft visual studio 8\vc\include\memory.:160]

 
--
Thanks.
0
lapucca
Asked:
lapucca
  • 5
  • 2
1 Solution
 
cwwkieCommented:
>      vector <CUserContextData*> userDataObjects;

I think you get this problem because you put pointers in the vector.
This way you copy only the pointer, but not the data itself. Because you have defined the assignment operator, default and copy constructor, you can put the element directly in the vector;

    vector <CUserContextData> userDataObjects;
0
 
cwwkieCommented:
And if you do want to put pointers in a vector, it's better to use a ptr_vector instead.
     http://www.boost.org/libs/ptr_container/doc/ptr_vector.html
     http://www.codeproject.com/vcpp/stl/ptr_vecto.asp
Or use a smart pointer like shared_ptr (http://www.boost.org/libs/smart_ptr/shared_ptr.htm).
0
 
lapuccaAuthor Commented:
Hi cwwkie,

I think it might be easier at this point for me to change the code and store bojects of my class in the vector, which means change the way I declare it and reference it.  I'll try it tomorrow and see if it works.  Also, do I need to change my class declaration, like the copy constructor or the operator=, descructor?   Can you see if it might be cause by any one of them?  I'm not sure about code that I wrote for those.  Thanks.
class CUserContextData
{
public:
            
    bool newObject, bWinLogOn, bUnifiedID, symarkEnabled, UIDChanged;
    wchar_t *shell, *homeDir, *primaryGroup, *symarkUserRef, *LoginName, *contextName;
       LPCWSTR lpcwContextName;
    int symarkUID, listViewIndex, UID;
      //std::wstring test;
      void CUserContextData::Copier(const CUserContextData &newUserData)
      {
            const wchar_t *lpcTemp;

            newObject = newUserData.newObject;
            bWinLogOn = newUserData.bWinLogOn;
            bUnifiedID = newUserData.bUnifiedID;
            symarkEnabled = newUserData.symarkEnabled;
            UIDChanged = newUserData.UIDChanged;
            symarkUID = newUserData.symarkUID;
            listViewIndex = newUserData.listViewIndex;
            UID = newUserData.UID;
             
            wchar_t *temp = new wchar_t[wcslen(newUserData.lpcwContextName)+1];
            wcscpy_s(temp, wcslen(newUserData.lpcwContextName)+1, newUserData.lpcwContextName);
            lpcwContextName = (LPCWSTR)temp;
            
            lpcTemp = T2CW(newUserData.contextName);
            contextName = new wchar_t[wcslen(newUserData.contextName)+1];
            wcscpy_s(contextName, wcslen(newUserData.contextName)+1, lpcTemp);

                        
            lpcTemp = T2CW(newUserData.LoginName);
            LoginName = new wchar_t[wcslen(newUserData.LoginName)+1];
            wcscpy_s(LoginName, wcslen(newUserData.LoginName)+1, (lpcTemp));


            lpcTemp = T2CW(newUserData.shell);
            shell = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy_s(shell, wcslen(lpcTemp)+1, (lpcTemp));

            lpcTemp = T2CW(newUserData.homeDir);
            homeDir = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy_s(homeDir, wcslen(lpcTemp)+1, (lpcTemp));

            lpcTemp = T2CW(newUserData.primaryGroup);
            primaryGroup = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy_s(primaryGroup, wcslen(lpcTemp)+1, (lpcTemp));

            lpcTemp = T2CW(newUserData.symarkUserRef);
            symarkUserRef = new wchar_t[wcslen(lpcTemp)+1];
            wcscpy_s(symarkUserRef, wcslen(lpcTemp)+1, (lpcTemp));
}
      void CUserContextData::DeleteUserContextData()
      {
            delete [] shell;
            delete [] homeDir;
            delete [] primaryGroup;
            delete [] symarkUserRef;
            //if(LoginName != NULL)
                  delete [] LoginName;
            delete [] contextName;
            delete [] lpcwContextName;
      }

      CUserContextData& CUserContextData::operator=(const CUserContextData& newUserData)
      {
            if(this != &newUserData)
            {
                  DeleteUserContextData();
                  Copier(newUserData);
            }
            return *this;
}

      CUserContextData::CUserContextData(void)
      {
            lpcwContextName = NULL;
            contextName = NULL;
            shell = NULL;
            homeDir = NULL;
            primaryGroup = NULL;
            symarkUserRef = NULL;
            LoginName = NULL;

            listViewIndex = NULL;
            UID = NULL;
            symarkUID=NULL;
            newObject = false; bWinLogOn = false; bUnifiedID = false; symarkEnabled = false; UIDChanged = false;
      }

      CUserContextData::CUserContextData(const CUserContextData &newUserData)
      {
            Copier(newUserData);
            
      }
      ~CUserContextData(void)
      {
            DeleteUserContextData();
      }


};
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
cwwkieCommented:
>  Also, do I need to change my class declaration, like the copy constructor or the operator=, descructor?

They look fine to me, but I might overlook something.

But I think this is a bit strange:
>          lpcTemp = T2CW(newUserData.contextName);
>          contextName = new wchar_t[wcslen(newUserData.contextName)+1];
>          wcscpy_s(contextName, wcslen(newUserData.contextName)+1, lpcTemp);

I don't see an error, but why not simply:
    contextName = new wchar_t[wcslen(newUserData.contextName)+1];
    wcscpy(contextName, newUserData.contextName);
or at least:
    contextName = new wchar_t[wcslen(newUserData.contextName)+1];
    wcscpy_s(contextName, wcslen(newUserData.contextName)+1, newUserData.contextName);
0
 
cwwkieCommented:
btw,

> I have a COM DLL that I'm working on using VS2005

This is the c++builder TA. It would have been better if you asked this in the normal c++ TA;
     http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/
You would get more help there.
0
 
lapuccaAuthor Commented:
Thank you.  I was thinkg about doing that.
BTW, I changed the code to store objects of my class but my program is staill crashing.  Do you think it might be becase the objects have wchar_t*, pointer type for data fields?      
vector <CUserContextData> userDataObjects;
      vector <CUserContextData>::iterator userDataIter;

Thanks.  
0
 
cwwkieCommented:
> Thank you.  I was thinkg about doing that.

Just saw you already did so.
You can ask a moderator to delete this question (http://www.experts-exchange.com/help.jsp#hi71)

you can also ask there to unaccept the answer of chip3d  in http:Q_21824169.html in case you selected the wrong comment.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now