Solved

memory errors in a Multi List

Posted on 2008-10-03
22
319 Views
Last Modified: 2013-11-17
Hi, I trying to do a SuperMarket Software. So..  products are divides in Sections, categories, and Lines. Well each section have some categories, and each category have some lines. I m doing this with binary files, I cannot use DB. I have coded a Double Linked List using templates (I have to do my own list I cant use std::list). So I had to do a multi list to manage sections,categories and lines together. All of this is defined in SectionsList unit and Data Unit.

Data is saved in Sec.dat, Cat.dat, Lin.Dat and MixData.dat. The last one has all links between sections,products and lines.

The problem is that when I store the information in a cSectionList class  I've got a memory error in the list class implemetation.

Im using Borland Builder C++6.0

Thanks ;)
//List Class 
#ifndef DoubleLinkedListH
#define DoubleLinkedListH
 
#ifndef NULL
#define NULL 0L
#endif
 
 
typedef unsigned int Size;
typedef unsigned int Pos;
 
template <typename T,bool dupe>
class cDoubleLinkedList
{
protected:
        struct Node
        {
                T  data;
                struct Node *next;
                struct Node *prev;
        };
        typedef struct Node * PNode;
 
private:
        PNode   m_pStart;
        PNode   m_pEnd;
        PNode   m_pPointer;
        Size    m_Count;
 
public:
        cDoubleLinkedList()
        {
                m_Count    = 0;
                m_pStart   = NULL;
                m_pEnd     = NULL;
                m_pPointer = NULL;
        }
        ~cDoubleLinkedList()
        {
                Free();
        }
        //Funciones de acceso
        bool InsertFirst(const T data);
        bool InsertOrder(const T data);//Ingresa los datos de menor a mayor
        bool AddEnd(const T data);
        bool DeleteFirst();
        bool DeleteEnd();
        bool InsertAt(const T data,Pos pos);
        bool DeleteAt(Pos pos);
        bool DeleteData(T data);
        Pos  Find(T data);
        T    GetElement(Pos pos);
        bool Update(T Old, T New);
        Size GetSize()const;
        void Free();//limpia la lista;
 
        //Funciones de desplazamiento
        void MoveFirst();
        void MoveNext();
        void MovePrev();
        void MoveEnd();
        bool IsEnd();
        T    GetCurrentElement();
 
        //Ordenamiento
        void Sort( bool(*ptrCmp)(T,T) );
        
};
//---------------------------------------------------------------------------
#endif
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::InsertFirst(const T data)
{
        if(dupe || Find(data)== -1)
        {
 
                PNode pNewNode = new Node;
                pNewNode->data = data;
                pNewNode->next = NULL;
                pNewNode->prev = NULL;
 
                if(m_pStart == NULL)
                        m_pEnd = pNewNode;
                else
                {
                        m_pStart->prev = pNewNode;
                        pNewNode->next = m_pStart;
                }
                m_pStart = pNewNode;
                m_Count++;
 
                return true;
        }
        return false;
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::InsertOrder(const T data)
{
        if(dupe || Find(data)== -1)
        {
                PNode pNewNode = new Node;
                pNewNode->data = data;
                pNewNode->next = NULL;
                pNewNode->prev = NULL;
                
                if(m_pStart == NULL)
                {
                        m_pStart = pNewNode;
                        m_pEnd   = pNewNode;
                }
                else
                {
                        PNode pTemp = new Node();
                        pTemp = m_pStart;
 
                        while(pTemp->next!=NULL && pTemp->data < pNewNode->data)
                                pTemp = pTemp->next;
 
 
                        if(pTemp->next == NULL)
                        {
                                m_pEnd->next = pNewNode;
                                pNewNode->prev = m_pEnd;
                                m_pEnd = pNewNode;
                        }
                        else
                        {
                                pNewNode->prev = pTemp;
                                pNewNode->next = pTemp->next;
                                pTemp->next->prev = pNewNode;
                                pTemp->next = pNewNode;
                        }
                }
                m_Count++;
 
                return true;
        }
        return false;
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::AddEnd(const T data)
{
        if( Find(data)== -1 || dupe )
        {
 
                PNode pNewNode = new Node();
                pNewNode->data = data;
                pNewNode->next = NULL;
                pNewNode->prev = NULL;
 
                if(m_pStart == NULL)
                        m_pStart = pNewNode;
                else
                {
                        m_pEnd->next = pNewNode;
                        pNewNode->prev = m_pEnd;
                }
                m_pEnd = pNewNode;
                m_Count++;
                return true;
        }
 
        return false;
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::DeleteFirst()
{
        if(m_pStart != NULL)
        {
                PNode p = m_pStart;
                if(m_pStart->next == NULL)
                {
                        m_pEnd = NULL;
                        m_pStart = NULL;
                }
                else
                {
                        m_pStart = m_pStart->next;
                        m_pStart->prev = NULL;
                }
                delete p;
                m_Count--;
        }
        return false;
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::DeleteEnd()
{
        if(m_pStart!=NULL)
        {
                PNode p = m_pEnd;
                if(m_pStart->next == NULL)
                {
                        m_pStart = NULL;
                        m_pEnd = NULL;
                }
                else
                {
                        m_pEnd = m_pEnd->prev;
                        m_pEnd->next = NULL;
                }
                delete p;
                m_Count--;
        }
        return false;
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::InsertAt(const T data,Pos pos)
{
        if(pos > 0 && pos < m_Count)
        {
                if(pos == 1)
                        InsertFirst(data);
                else if(pos == m_Count)
                        AddEnd(data);
                else
                {
                        PNode pNewNode = new Node();
                        pNewNode->data = data;
                        pNewNode->next = NULL;
                        pNewNode->prev = NULL;
 
                        PNode p = m_pStart;
 
                        for(Pos i = 1;i<=pos-2;i++)
                                p = p->next;
 
                        pNewNode->prev = p;
                        pNewNode->next = p->next;
                        p->next->prev = pNewNode;
                        p->next = pNewNode;
 
                        m_Count++;
                }
        }
        return false;
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::DeleteAt(Pos pos)
{
        try{
                if(m_pStart != NULL)
                {
                        if(pos > 0 && pos <= m_Count)
                        {
                                if(pos == 1)
                                        DeleteFirst();
                                else if(pos == m_Count)
                                        DeleteEnd();
                                else
                                {
                                        PNode p = m_pStart;
                                        for(Pos i=1 ;i<=pos-1;i++)
                                                p = p->next;
                                        p->prev->next = p->next;
                                        p->next->prev = p->prev;
                                        delete p;
                                        m_Count--;
 
                                }
                                return true;
                        }
                        return false;
                }
 
                return false;
        }catch(...)
        {
                return false;
        }
 
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::DeleteData(T data)
{
        Pos pos = Find(data);
        return DeleteAt(pos);
}
 
template <typename T,bool dupe>
Pos  cDoubleLinkedList<T,dupe>::Find(T data)
{
        Pos pos = -1, i = 1;
        PNode pTemp = m_pStart;
 
        while(i <= m_Count && pos == -1)
        {
                if(pTemp->data == data)
                        pos = i;
                i++;
                pTemp = pTemp->next;
        }
        return pos;
}
 
template <typename T,bool dupe>
T    cDoubleLinkedList<T,dupe>::GetElement(Pos pos)
{
        if(pos > 0 && pos <= m_Count)
        {
                PNode pTemp = m_pStart;
                for(Pos i=1;i<pos-1;i++)
                        pTemp = pTemp->next;
 
                return pTemp->data;
        }
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::Update(T Old, T New)
{
        Pos pos = Find(Old);
        if(pos != -1)
        {
                PNode pTemp = m_pStart;
                for(Pos i=1;i<m_Count;i++)
                {
                        if(pTemp->data == Old)
                        {
                                pTemp->data = New;
                                return true;
                        }
                        pTemp = pTemp->next;
                }
                return false;
        }
        return false;
}
 
template <typename T,bool dupe>
Size cDoubleLinkedList<T,dupe>::GetSize()const
{
        return m_Count;
}
 
template <typename T,bool dupe>
void cDoubleLinkedList<T,dupe>::Free()
{
        PNode node;
        while(m_pStart != NULL)
        {
                node = m_pStart;
                m_pStart = m_pStart->next;
                delete node;
        }
        delete m_pPointer;
        m_pEnd = NULL;
}
 
 
template <typename T,bool dupe>
void cDoubleLinkedList<T,dupe>::MoveFirst()
{
        m_pPointer = m_pStart;
}
 
template <typename T,bool dupe>
void cDoubleLinkedList<T,dupe>::MoveNext()
{
        m_pPointer = m_pPointer->next;
}
template <typename T,bool dupe>
void cDoubleLinkedList<T,dupe>::MovePrev()
{
        m_pPointer = m_pPointer->prev;
}
template <typename T,bool dupe>
void cDoubleLinkedList<T,dupe>::MoveEnd()
{
        m_pPointer = m_pEnd;
}
 
template <typename T,bool dupe>
bool cDoubleLinkedList<T,dupe>::IsEnd()
{
        return (m_pPointer == NULL);      
}
 
template <typename T,bool dupe>
T    cDoubleLinkedList<T,dupe>::GetCurrentElement()
{
        return m_pPointer->data;
}
 
template <typename T,bool dupe>
void cDoubleLinkedList<T,dupe>::Sort( bool(*ptrCmp)(T d1,T d2) )
{
        PNode p = m_pStart;
        PNode q = p->next;
 
        for(Pos i=0;i<m_Count;i++)
        {
                for(Pos j=i+1;j<m_Count-1;j++)
                {
                        if(ptrCmp(p->data,q->data))
                        {
                                T temp = p->data;
                                p->data = q->data;
                                q->data = temp;
                        }
                }
        }
}
 
#endif
//Data File
 
#ifndef DataH
#define DataH
 
#include <string.h>
#include <ctype.h>
#include "ListaDoble.cpp"
#include "FileManager.cpp"
 
//Estructura de una seccion, catgoria o linea
 
typedef struct __sData__
{
        unsigned int    code;
        char            des[50];
        __sData__();
        
        bool operator<(const __sData__ &other);
        bool operator==(const __sData__ &other);
        __sData__ & operator=(const unsigned int code);
        __sData__ & operator=(const char * des);
        __sData__ & operator=(const __sData__ &other);
}sData;
 
class cData
{
protected:
        cDoubleLinkedList<__sData__,false>      m_list;
        char                                    m_filename[10];
        static bool Cmp(sData,sData);
public:
        cData();
        virtual ~cData();
 
        //Funciones de agregado,eliminado,etc
        virtual bool InsertOrder(const sData);
        virtual bool Delete(const sData);
        virtual bool Update(sData,sData);
 
        //Funciones de recorrido
        virtual void MoveFirst();
        virtual void MoveNext();
        virtual void MovePrev();
        virtual void MoveEnd();
        virtual bool IsEnd();
        virtual void GetElement(sData*);
        virtual void GetElementAdd(sData*);
        virtual sData FindElement(unsigned int code);
        virtual void Sort();
 
        Size GetSize()const;
 
        //Funciones para cargar y guardar la lista
        virtual bool Save();
        virtual bool Load();
public:
};
//---------------------------------------------------------------------------
#endif
 
 __sData__::__sData__()
{
        code = 0;
        strcpy(des,"");
}
 
bool __sData__::operator<(const __sData__ &other)
{
        if (this->code < other.code)
                return true;
        return false;
}
bool __sData__::operator==(const __sData__ &other)
{
        if(this->code == other.code)
                return true;
        else if( strcmp(this->des,other.des)==0 )
                return true;
        else
                return false;
}
__sData__ & __sData__::operator=(const unsigned int code)
{
        this->code = code;
        return (*this);
}
__sData__ & __sData__::operator=(const char * des)
{
        /*char * anDes;//cadena alfa numerica
        anDes = new char[50];
 
        for(unsigned int i=0;i<strlen(des);i++)
        {
                if( isalnum(des[i]) )
                {
                        anDes[i]=des[i];
                        anDes[i]=toupper(anDes[i]);
                }
                else
                        anDes[i]=45;//Se llena con espacios en blanco
        }
        strcpy(this->des,anDes);  */
        strcpy(this->des,des);
        return (*this);
}
__sData__ & __sData__::operator=(const __sData__ &other)
{
        (*this) = other.code;
        (*this) = other.des;
        return (*this);
}
 
 
cData::cData()
{
        strcpy(m_filename,"DefData.dat");
}
cData::~cData()
{
        m_list.Free();
}
 
bool cData::Cmp(sData d1,sData d2)
{
        return (d1.code>d2.code);
}
 
//Funciones de agregado,eliminado,etc
bool cData::InsertOrder(const sData data)
{
        //return m_list.InsertOrder(data);
        return m_list.AddEnd(data);
}
bool cData::Delete(const sData data)
{
        return m_list.DeleteData(data);
}
bool cData::Update(sData Old,sData New)
{
        return m_list.Update(Old,New);
}
 
//Funciones de recorrido
void cData::MoveFirst()
{
        m_list.MoveFirst();
}
void cData::MoveNext()
{
        m_list.MoveNext();
}
void cData::MovePrev()
{
        m_list.MovePrev();
}
void cData::MoveEnd()
{
        m_list.MoveEnd();
}
bool cData::IsEnd()
{
        return m_list.IsEnd();
}
void cData::GetElement(sData * data)
{
        (*data) = m_list.GetCurrentElement();
}
void cData::GetElementAdd(sData * data)
{
        data = &m_list.GetCurrentElement();
}
sData cData::FindElement(unsigned int code)
{
        m_list.MoveFirst();
        while(!m_list.IsEnd())
        {
                sData data = m_list.GetCurrentElement();
                if(data.code == code)
                        return data;
                m_list.MoveNext();
        }
}
void cData::Sort()
{
        m_list.Sort(Cmp);
}
Size cData::GetSize()const
{
        return m_list.GetSize();
}
 
bool cData::Save()
{
        cFileStream<__sData__>  m_Stream;
        if(!m_Stream.Create(m_filename,F_BINARY_REPLACE_WRITE))
                return false;
 
        m_Stream.SetPosBegin();
        m_list.MoveFirst();
        
        sData data;
        while(!m_list.IsEnd())
        {
                data = m_list.GetCurrentElement();
                m_Stream.Write(&data,1);
                m_list.MoveNext();
        }
        m_Stream.Close();
        return true;
}
bool cData::Load()
{
        cFileStream<__sData__>  m_Stream;
        if(m_Stream.Create(m_filename,F_BINARY_OPEN_READ))
        {
 
                m_Stream.SetPosBegin();
                m_list.Free();
 
                sData data;
                while( m_Stream.Read(&data,1)>0 )
                        m_list.InsertOrder(data);
 
                m_Stream.Close();
                return true;
        }
        return false;
}
 
//SectionList File
#ifndef SectionListH
#define SectionListH
 
#include "DataFile.h"
#include "vcl.h"
 
 
//Clase que maneja multilistas Sec,Cat,Lin
 
class cCategory
{
private:
        sData                               m_Data;
        cDoubleLinkedList<sData*,false>     m_lstLine;//Conjunto de listas
public:
        cCategory();
        cCategory(sData);
        ~cCategory();
 
        bool AddLine(sData);
        int  AddLineAll(cLineListFile*);
 
        bool operator<(const cCategory &other);
        bool operator==(const cCategory &other);
};
 
class cSection
{
private:
        sData                                   m_Data;
        cDoubleLinkedList<cCategory,false>      m_lstCat;//Lista de categorias
public:
        cSection();
        cSection(sData);
 
        unsigned int GetCode()const;
        char * GetDes();
 
        bool AddCategory(cCategory*);
 
        bool operator<(const cSection &other);
        bool operator==(const cSection &other);
};
 
class cSectionList
{
private:
        unsigned int                             m_uCode;
        cDoubleLinkedList<cSection,false>       m_lstSec;//Lista de categorias
public:
 
        bool AddSection(cSection);
        bool AddCategory(cSection,cCategory);
 
        void MoveFirst();
        void MoveNext();
        bool IsEnd();
        void GetElement(cSection*);
};
 
 
 
//Estructura para relazionar los 3 tipos de datos
typedef struct __sMixData__
{
        unsigned int    code_sec;//Codigo de seccion
        unsigned int    code_cat;//Codigo de categoria
        unsigned int    code_lin;//Codigo de linea
 
        bool operator<(const __sMixData__ &other);
        bool operator==(const __sMixData__ &other);
}sMixData;
 
//Clase que maneja los datos
class cMixData
{
private:
        cDoubleLinkedList<__sMixData__,false>   m_list;
        char                                    m_filename[10];
 
        cSectionListFile    *                   m_pSecData;
        cCategoryListFile   *                   m_pCatData;
        cLineListFile       *                   m_pLinData;
protected:
        static bool Sec(sMixData,sMixData);
        static bool Cat(sMixData,sMixData);
        static bool Lin(sMixData,sMixData);
public:
        cMixData(cSectionListFile*,cCategoryListFile*,cLineListFile*);
 
        bool AddMix(sMixData);
 
        bool Load();
        bool Save();
        void ProcessData(cSectionList*);
};
 
#endif
 
/*******************************************************************
                        cCategory Class
*******************************************************************/
cCategory::cCategory()
{
}
cCategory::cCategory(sData sData)
{
        this->m_Data = sData;
}
cCategory::~cCategory()
{
        m_lstLine.Free();
}
 
bool cCategory::AddLine(sData line)
{
        return m_lstLine.InsertOrder(&line);
}
int  cCategory::AddLineAll(cLineListFile * pLF)
{
        unsigned int added = 0;
        if(pLF != NULL)
        {
                sData * line;
                pLF->MoveFirst();
                pLF->GetElementAdd(line);
                added+=(m_lstLine.InsertOrder(line))?1:0;
        }
        return added;
}
 
bool cCategory::operator<(const cCategory &other)
{
        if( (this->m_Data) < (other.m_Data) )
                return true;
        return false;
}
bool cCategory::operator==(const cCategory &other)
{
        if( (this->m_Data)== (other.m_Data) )
                return true;
        return false;
}
/******************************************************************/
 
/*******************************************************************
                        cSection Class
*******************************************************************/
cSection::cSection()
{
}
cSection::cSection(sData pData)
{
        this->m_Data = pData;
}
 
unsigned int cSection::GetCode()const
{
        return m_Data.code;
}
char * cSection::GetDes()
{
        return m_Data.des;
}
 
bool cSection::AddCategory(cCategory * cat)
{
        return m_lstCat.AddEnd(*cat);
}
 
bool cSection::operator<(const cSection &other)
{
        if( (this->m_Data) < (other.m_Data) )
                return true;
        return false;
}
bool cSection::operator==(const cSection &other)
{
        if( (this->m_Data) == (other.m_Data) )
                return true;
        return false;
}
/*******************************************************************/
 
/*******************************************************************
                        cSectionList Class
*******************************************************************/
bool cSectionList::AddSection(cSection sec)
{
        return m_lstSec.InsertOrder(sec);
}
bool cSectionList::AddCategory(cSection sec,cCategory cat)
{
        Pos pos = m_lstSec.Find(sec);
        return true;//m_lstSec.GetElement(pos).AddCategory(cat);
}
 
void cSectionList::MoveFirst()
{
        m_lstSec.MoveFirst();
}
void cSectionList::MoveNext()
{
        m_lstSec.MoveNext();
}
bool cSectionList::IsEnd()
{
        return m_lstSec.IsEnd();
}
void cSectionList::GetElement(cSection * pSec)
{
        *pSec = m_lstSec.GetCurrentElement();
}
 
/*******************************************************************
                        __sMixData__ Struct
*******************************************************************/
bool __sMixData__::operator<(const __sMixData__ &other)
{
        if(this->code_sec < other.code_sec)
                return true;
        else if(this->code_sec == other.code_sec)
        {
                if(this->code_cat < other.code_cat)
                        return true;
                else if(this->code_cat == other.code_cat)
                {
                        if(this->code_lin < other.code_lin)
                                return true;
                        else
                                return false;
                }
                else
                        return false;
        }
        else
                return false;
 
}
bool __sMixData__::operator==(const __sMixData__ &other)
{
        if(this->code_sec == other.code_sec &&
           this->code_cat == other.code_cat &&
           this->code_lin == other.code_lin)
                return true;
        return false;
}
/******************************************************************/
 
/*******************************************************************
                        __sMixData__ Class
*******************************************************************/
cMixData::cMixData(cSectionListFile * pSF,cCategoryListFile * pCF,cLineListFile * pLF)
{
        this->m_pSecData = pSF;
        this->m_pCatData = pCF;
        this->m_pLinData = pLF;
        strcpy(m_filename,"MixData.dat");
}
bool cMixData::Sec(sMixData d1,sMixData d2)
{
        return (d1.code_sec<d2.code_sec);
}
bool cMixData::Cat(sMixData d1,sMixData d2)
{
        return (d1.code_cat<d2.code_cat);
}
bool cMixData::Lin(sMixData d1,sMixData d2)
{
        return (d1.code_lin<d2.code_lin);
}
bool cMixData::AddMix(sMixData data)
{
        return m_list.InsertOrder(data);
}
bool cMixData::Load()
{
        cFileStream<__sMixData__>  m_Stream;
        if(!m_Stream.Create(m_filename,F_BINARY_OPEN_READ_WRITE))
                return false;
 
        m_Stream.SetPosBegin();
        m_list.Free();
 
        sMixData data;
        while(m_Stream.Read(&data,1)>0)
                m_list.InsertOrder(data);
 
        m_Stream.Close();
        return true;
}
bool cMixData::Save()
{
        cFileStream<__sMixData__>  m_Stream;
        if(!m_Stream.Create(m_filename,F_BINARY_REPLACE_WRITE))
                return false;
 
        m_Stream.SetPosBegin();
        m_list.MoveFirst();
        while(!m_list.IsEnd())
        {
                sMixData data;
                data = m_list.GetCurrentElement();
                m_Stream.Write(&data,1);
                m_list.MoveNext();
        }
        m_Stream.Close();
        return true;
}
void cMixData::ProcessData(cSectionList * pLstSec)
{
        //Recorrer lista de archivos cargados
        m_list.Sort(Cat);
 
        for( m_pSecData->MoveFirst() ; !m_pSecData->IsEnd() ; m_pSecData->MoveNext() )
        {
                sData SecData;
                m_pSecData->GetElement(&SecData);
                cSection sec(SecData);
 
                for( m_pCatData->MoveFirst() ; !m_pCatData->IsEnd() ; m_pCatData->MoveNext())
                {
                        sData CatData;
                        m_pCatData->GetElement(&CatData);
                        cCategory cat(CatData);
 
                        m_list.MoveFirst();
                        while(!m_list.IsEnd())
                        {
                                sMixData MD;
 
                                MD = m_list.GetCurrentElement();
                                if(CatData.code == MD.code_cat)
                                {
                                        sData LinData = m_pLinData->FindElement(MD.code_lin);
                                        cat.AddLine(LinData);
                                }
                                m_list.MoveNext();
                        }
                        sec.AddCategory(&cat);//HERE I GOT THE ERROR
                }
                pLstSec->AddSection(sec);
        }
}

Open in new window

0
Comment
Question by:manganzon
  • 11
  • 10
22 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 22642801
>> I've got a memory error in the list class implemetation.

What is the error you get ? Can you describe in more detail what is going wrong, what you observe, etc. ?
0
 

Author Comment

by:manganzon
ID: 22644364
Yes, the error is:

TrabajoEs.exe raised exception class EAccessViolation with message Access Violation at adress 00405573 in module 'TrabajoEs.exe'. Read of Adress 0000014 Process stoped. Use step to run to continue.

The line code of this message is:
template <typename T,bool dupe>
void cDoubleLinkedList<T,dupe>::Free()
{
        PNode node;
        while(m_pStart != NULL)
        {
                node = m_pStart;
                m_pStart = m_pStart->next;//HEREEE
                delete node;
        }
        delete m_pPointer;
        m_pEnd = NULL;
}

and as said, the error is when the program execute this line:

sec.AddCategory(&cat);

if I comment this line then there is no problem

0
 

Author Comment

by:manganzon
ID: 22644690
I can upload the entire project but I dont know if it is allowed :S
0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 53

Expert Comment

by:Infinity08
ID: 22644910
>> Read of Adress 0000014

That means that you're trying to read an invalid memory location. There can be several reasons, for example :

(a) you interpret a regular value (20 decimal in this case) as a pointer, and dereference it.

(b) a pointer was overwritten (by a buffer overflow or similar) by that value


>> and as said, the error is when the program execute this line:

Can you show how you call AddCategory ?
0
 

Author Comment

by:manganzon
ID: 22645125
sure:

class cSection
{
private:
        sData                                   m_Data;
        cDoubleLinkedList<cCategory,false>      m_lstCat;
.
.
.
};
bool cSection::AddCategory(cCategory * cat)
{
        return m_lstCat.AddEnd(*cat);
}

I also tried to do this:
class cSection
{
private:
        sData                                   m_Data;
        cDoubleLinkedList<cCategory,false>      m_lstCat;
.
.
.
};
bool cSection::AddCategory(cCategory  cat)
{
        return m_lstCat.AddEnd(cat);
}

and this:

class cSection
{
private:
        sData                                   m_Data;
        cDoubleLinkedList<cCategory*,false>      m_lstCat;
.
.
.
};
bool cSection::AddCategory(cCategory  * cat)
{
        return m_lstCat.AddEnd(cat);
}

but doesnt works :/
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22645269
I tried to get the source compiled but in line 71 there is an #endif which has no starting #if ...
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22645386
>> sure:

You didn't show how you called it. You just showed its implementation.
0
 

Author Comment

by:manganzon
ID: 22645481
>> I tried to get the source compiled but in line 71 there is an #endif which has no starting #if ...
Yes it has:

#ifndef DoubleLinkedListH

>> You didn't show how you called it. You just showed its implementation.

sry I didnt understand what you mean. Maybe u mean this:


void cMixData::ProcessData(cSectionList * pLstSec)
{
        //Recorrer lista de archivos cargados
        m_list.Sort(Cat);
 
        for( m_pSecData->MoveFirst() ; !m_pSecData->IsEnd() ; m_pSecData->MoveNext() )
        {
                sData SecData;
                m_pSecData->GetElement(&SecData);
                cSection sec(SecData);
 
                for( m_pCatData->MoveFirst() ; !m_pCatData->IsEnd() ; m_pCatData->MoveNext())
                {
                        sData CatData;
                        m_pCatData->GetElement(&CatData);
                        cCategory cat(CatData);
 
                        m_list.MoveFirst();
                        while(!m_list.IsEnd())
                        {
                                sMixData MD;
 
                                MD = m_list.GetCurrentElement();
                                if(CatData.code == MD.code_cat)
                                {
                                        sData LinData = m_pLinData->FindElement(MD.code_lin);
                                        cat.AddLine(LinData);
                                }
                                m_list.MoveNext();
                        }
                        sec.AddCategory(&cat);//HERE I GOT THE ERROR
                }
                pLstSec->AddSection(sec);
        }
}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22645511
>>                         sec.AddCategory(&cat);//HERE I GOT THE ERROR

AddCategory expects a cCategory object as parameter, but you're passing it a pointer to a cCategory object. It shouldn't even compile ...
0
 

Author Comment

by:manganzon
ID: 22645538
No, because Im using this implementation:

class cSection
{
private:
        sData                                   m_Data;
        cDoubleLinkedList<cCategory,false>      m_lstCat;
.
.
.
};
bool cSection::AddCategory(cCategory * cat)
{
        return m_lstCat.AddEnd(*cat);
}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22645596
In that case, be very careful about storing pointers to local data in containers.

For example, the m_lstLine of the cCategory class stores pointers to sData objects. But the pointers you store in it, are pointers to local objects (that have a limited scope) :

bool cCategory::AddLine(sData line)
{
        return m_lstLine.InsertOrder(&line);
}

The pointer stored in the list is a pointer to the local function copy of the line object, that goes out of scope as soon as the function ends.
0
 

Author Comment

by:manganzon
ID: 22645676
So what should I do? I have changed:

bool cCategory::AddLine(sData line)
{
        return m_lstLine.InsertOrder(&line);
}

for:

bool cCategory::AddLine(sData * lline)
{
        return m_lstLine.InsertOrder(line);
}

and:

                                MD = m_list.GetCurrentElement();
                                if(CatData.code == MD.code_cat)
                                {
                                        sData LinData = m_pLinData->FindElement(MD.code_lin);
                                        cat.AddLine(&LinData);
                                }

In this lines:

sData LinData = m_pLinData->FindElement(MD.code_lin);
 cat.AddLine(&LinData);

LinData also have limited scope? so how can I store pointers that are in ohter list :S
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22645686
>> So what should I do?

Depends on what you want to do. In general, you always have to be aware of where data is, and what its lifetime is. Data on the stack (statically allocated) has a lifetime that corresponds to the enclosing block, while dynamically allocated data stays in memory until it's explicitly free'd.

Either you want to store pointers in the container, and in that case, you probably want to use dynamically allocated memory for storing the objects the pointers point to.
Or you want to store copies of the data like you did in almost all your other containers.

That said, your code performs a LOT of copies when passing parameters and storing data in containers. Consider making better use of pointers and references instead. It's a lot cleaner and definitely faster.
0
 

Author Comment

by:manganzon
ID: 22645721
>> Either you want to store pointers in the container, and in that case, you probably want to use dynamically allocated memory for storing the objects the pointers point to.

How can I do that? :)
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22645863
I would suggest to read up on dynamic memory. Here's a nice tutorial :

        http://www.cplusplus.com/doc/tutorial/dynamic.html
0
 

Author Comment

by:manganzon
ID: 22645937
I already know that..  new, delete, dynamic arrays, etc... but what I have is a class that load data from a file like this:

class cData
{
protected:
        cDoubleLinkedList<__sData__,false>      m_list;
        char                                    m_filename[10];
...
};

it must be a list, it cant be arrays or dynamic arrays.

Then i have to connect a category with some lines and a section with some categories and the put all together in a sectionlist.

e.g.

class cCategory
{
private:
     cDoubleLinkedList<sData*,false>
};

Then I have to store (in cCategory class) some pointers to sData loaded from cData class.  So if the node of my list is like this:

        struct Node
        {
                T  data;//T = sData;
                struct Node *next;
                struct Node *prev;
        };

I suposse I need to get the data adress memory and store it in cCategory Class right? or Im wrong?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22645965
>> it must be a list, it cant be arrays or dynamic arrays.

That doesn't matter :) The only thing that you need to make sure of is, that if you're storing pointers in a container, that those pointers point to dynamically allocated memory, not to local (statically allocated) objects.
0
 

Author Comment

by:manganzon
ID: 22646057
so if I have to to this:

sData * pData = new sData();

cCategory * pCat = new pCategory();

pCat->AddLine(pData);

cSection * pSection = new pSection();

pSection->Add Category(pCat);

??

I mean I always have to do:

MyClass * cl = new MyClass();

instead of MyClass cl; ??
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22646078
>> I mean I always have to do:

Only when you're storing pointers. If you're storing copies, you don't need to dynamically allocate data.


Note that you shouldn't forget to delete the memory again once you don't need it any more.
0
 

Author Comment

by:manganzon
ID: 22646126
one more thing, If I want to write the data in a file will I have any problem? I can follow the same procedure:

bool cData::Save()
{
        cFileStream<__sData__>  m_Stream;
        if(!m_Stream.Create(m_filename,F_BINARY_REPLACE_WRITE))
                return false;

        m_Stream.SetPosBegin();
        m_list.MoveFirst();
       
        sData * data;
        while(!m_list.IsEnd())
        {
                data = m_list.GetCurrentElement();
                m_Stream.Write(data,1);
                m_list.MoveNext();
        }
        m_Stream.Close();
        return true;
}
bool cData::Load()
{
        cFileStream<__sData__>  m_Stream;
        if(m_Stream.Create(m_filename,F_BINARY_OPEN_READ))
        {

                m_Stream.SetPosBegin();
                m_list.Free();

                sData * data = new sData();
                while( m_Stream.Read(data,1)>0 )
                        m_list.InsertOrder(data);

                m_Stream.Close();
                return true;
        }
        return false;
}

Class is here: (the type name in the cFileStreamClass musbt be sData or sData*)??


template <typename T>
void cFileStream<T>::Write(const T * data,int count)
{
        if(m_pFile!=NULL)
        {
                fwrite(data,sizeof(T),count,m_pFile);
                m_Pos = ftell(m_pFile);
        }
}
 
template <typename T>
int cFileStream<T>::Read(T *  data,int count)
{
        int sz = fread(data,sizeof(T),count,m_pFile);
        m_Pos = ftell(m_pFile);
        return sz;
}

Open in new window

0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 250 total points
ID: 22646182
>> will I have any problem?

As long as you don't write the pointer itself, but rather the data it points to, to the file, there should be no problem.
0
 

Author Closing Comment

by:manganzon
ID: 31502967
Thank you very much ;)
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Excel/Word Add-in in what language? 5 118
FMX StringGrid1->Canvas->FillRect Problem 3 150
Copying WordPress Pages 5 82
eclipse package explorer vs project explorer view 2 122
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

786 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question