Solved

memory errors in a Multi List

Posted on 2008-10-03
22
315 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
Comment Utility
>> 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
Comment Utility
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
Comment Utility
I can upload the entire project but I dont know if it is allowed :S
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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
Comment Utility
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
Comment Utility
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
Comment Utility
>> sure:

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

Author Comment

by:manganzon
Comment Utility
>> 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
Comment Utility
>>                         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
Comment Utility
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
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:manganzon
Comment Utility
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
Comment Utility
>> 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
Comment Utility
>> 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
Comment Utility
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
Comment Utility
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
Comment Utility
>> 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
Comment Utility
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
Comment Utility
>> 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
Comment Utility
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
Comment Utility
>> 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
Comment Utility
Thank you very much ;)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

763 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now