views:

188

answers:

3

I am new to C++. I am getting HEAP CORRUPTION ERROR. Any help will be highly appreciated. Below is my code

class CEntity  
{  
//some member variables  
CEntity(string section1,string section2);  
CEntity();  
virtual ~CEntity();  
//pure virtual function ..  
virtual CEntity* create()const = 0;  
};  

I derive CLine from CEntity as below

class CLine:public CEntity  
{  
// Again some variables ...  
// Constructor and destructor  
CLine(string section1,string section2);  
CLine();  
~CLine();  
CLine* Create() const;  
}  

// CLine Implementation  
CLine::CLine(string section1,string section2) : CEntity(section1,section2){};  
CLine::CLine();  
CLine* CLine::create() const {return new CLine();}  

I have another class CReader which uses CLine object and populates it in a multimap as below

class CReader  
{  
public:  
CReader();  
~CReader();  
multimap<int,CEntity*>m_data_vs_entity;  
};  

//CReader Implementation  
CReader::CReader()  
{  
  m_data_vs_entity.clear();  
};  

CReader::~CReader()  
{  
  multimap<int,CEntity*>::iterator iter;  
  for(iter = m_data_vs_entity.begin();iter!=m_data_vs_entity.end();iter++)  
  {  
    CEntity* current_entity = iter->second;  
    if(current_entity)  
      delete current_entity;  
  }  
  m_data_vs_entity.clear();  
}  

I am reading the data from a file and then populating the CLine Class.The map gets populated in a function of CReader class. Since CEntity has a virtual destructor, I hope the piece of code in CReader's destructor should work. In fact, it does work for small files but I get HEAP CORRUPTION ERROR while working with bigger files. If there is something fundamentally wrong, then, please help me find it, as I have been scratching my head for quit some time now.
Thanks in advance and awaiting reply,
Regards,
Atul

Continued from Y'day : Further studying this in detail I now have realized that Heap allocation error in my case is because I am allocating something, and then overwriting it with a higher size. Below is the code where in my data gets populated in the constructor.

CEntity::CEntity(string section1,string section2)
{
    size_t length;
    char buffer[9];
    //Entity Type Number
    length = section1.copy(buffer,8,0);
    buffer[length]='\0';
    m_entity_type = atoi(buffer);

    //Parameter Data Count
    length = section1.copy(buffer,8,8);
    buffer[length]='\0';
    m_param_data_pointer = atoi(buffer);
        //.... like wise ....
}

I am getting the values at a fixed interval of 8 chars and I am adding a '\0' so this, i guess will take care of any garbage value that I encounter.

About Heap allocation error: after normal block (XXX) at XXX, CRT detected that application wrote to memory after end of Heap buffer. Mostly, Heap allocation errors occur somewhere else than where it crashes. I would appreciate if some one here would help me, how to make use of this normal block and the address. Thanks,

+1  A: 

Well, you're only showing half the problem.

Where's the code that creates the CLine objects and stores them in the CReader?

Also, what do you consider actually "owns" the CEntity objects? Generally, you should make the 'owner' responsible for creation as well as deletion...

I wrote earlier:

"You might like to consider storing the CEntitys directly in the map, rather than storing pointers. Potentially less efficient, but also much less scope for cockups."

As Neil points out, it's not CEntities that you will be storing, so that suggestion isn't going to help you much...

Roddy
He can't store CEntities in anything - it's an abstract class.
anon
The capital C is probably only a typo, don't you think?
struppi
@ Roddy: Meaning, instead of the multimap <int,CEntity*>, I should have a multimap of <int,void*>, and I should directly store the inherited entities that is CLine etc ?
Atul
@Atul, No, I meant multimap<int, CEntity>. But I hadn't appreciated the polymorphic nature of the problem, so it won't work exactly like that.
Roddy
@Roddy: Further research on this lead me to the revelation that I am allocating
Atul
A: 

@Naveen, you are right, I am not using the create function as of now, My purpose for that function was just to make CENtity class abstract. I am putting in the process_entity function here for your reference.

 bool CReader::process_entity(string section1,string section2)
    {  
    size_t length;  
    char buffer[9];  
    length = section1.copy(buffer,8,0);  
    buffer[length]='\0';  
    int ent_type = atoi(buffer);  
    CEntity* current_ent = NULL;  
    switch(ent_type)  
    {  
    case 110: 
    {
    CLine* line_entity = new CLine(section1,section2);
    current_ent = line_entity;
    break;
    }  
    default:
    {
        break;
    }
    if(current_ent != NULL)  
    {  
     // One of the get methods from CEntity class get's called ...  
     int PD_Pointer = current_ent->get_parameter_data_ptr();  
    m_data_vs_entity.insert(pair<int,CEntity*>(PD_Pointer,current_ent));  
    }  
    return true;  
    }
Atul
In the original question you had `m_data_vs_entity` map, here you have `m_paramdata_vs_entity` are they same? or there are two maps?
Naveen
yup, they are the same, please refer the latest process_entity function
Atul
it's offtopic, but why do you create buffer and make a copy setting a null terminator instead of just using atoi( section1.c_str() ) ?
Dmitry Yudakov
Could anybody found what's wrong in here please ? In the meantime, I tried using application verifier to track memory related issues, but it doesn't seem to find anything. Also ,i read somewhere in this forum about HEAP corruption causing due to Pointers not initializing properly. I guess I am doing that too. Any help ???
Atul
@Dmitry: The reason is that, I am getting information that needs to be tokanized.section 1 and section2 contains a bunch of values that are used to set my data members.
Atul
A: 

Finally, after two days of debugging, I was able to fix up the crash. It was due to me copying wrong number of characters from the string.
Lessons learnt :
1. When you encounter memory allocation errors, try to form a simple test case which has minimum entities to reproduce the problem.
2. A sure shot way is a line by line debugging. I agree,it test your patience, but then, there are no short cuts to success
3. And it gives you a chance to do a code review, further enhancing the quality of code that you produce in future

Thank you for all your help and formatting my code :)
Regards,
Atul

Atul
@Atul One more bit of advice. Do not post additions to your question, extra code, explanations etc. as answers - edit them into your original question.
anon