Why I am getting a Heap Corruption Error? - c++

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,

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...

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

Related

Feed a QList with another

hi i'm trying to send a QList as a parameter to another class but for some reason i got a read access violation...
CompareTimeChannel.h
class CompareTimeChannel : public IDataChannel
public:
// #brief The method used to receive the list
void setData(const QList< QSharedPointer<core::ITrackSection> > & sections);
// #brief The list
QList< QSharedPointer<core::ITrackSection> > _sections;
};
CompareTimeChannel.cpp
// #brief Empty constructor
CompareTimeChannel::CompareTimeChannel()
{
}
void CompareTimeChannel::setData(const QList< QSharedPointer<core::ITrackSection> > & sections)
{
//_sections = *new QList< QSharedPointer<core::ITrackSection> > ();
_sections.clear();
_sections.append(sections);
}
Running this code will throw Exception at 0x31cc78d, code: 0xc0000005: read access violation at: 0x4, flags=0x0 on _sections.clear();
I tried to initialize the list before (the commented line _sections = *new QList<...>) but the exception is thrown the same.
An answer would be very appreciated...
EDIT
Ok it's fixed!
First, like #AndreasT said, i had to initialize the default QList constructor.
Then, according to #10WaRRioR01 's answer, the issue comes from CompareTimeChannel which wasn't initialized the first time the method was called. Fixed using :
CompareTimeChannel* chan = static_cast<CompareTimeChannel*>(channel);
Q_ASSERT(chan);
if (chan) {
chan->setData(sections);
}
else {
qDebug() << "Dynamic cast failure";
}
Thank you all, guys!
//_sections = *new QList< QSharedPointer<core::ITrackSection> > ();
You shouldn't ever do something like this. This creates a new instance of QList on the heap and it will never be deleted, so you have a memory leak
You should have done
_sections = QList< QSharedPointer<core::ITrackSection> > ();
instead, and it would be legal. But the most simple way is to use a copy assignment like this
_sections = sections
The problem you got is most likely related to the data you have in _sections. Maybe you are calling your methods on a null CompareTimeChannel object
You should initialize sections in the constructor.
The commented line is just horribly wrong.
new constructs the List on the heap, then you dereference that with *new and the assignment implicitly calls the copy constructor of the new list on the Heap and copies that into the instance. The thing on the heap is still aruond though, so you just created a memory leak.
// #brief Empty constructor
CompareTimeChannel::CompareTimeChannel()
:_sections() // initialization default constructor.
{
}
Edit regarding the comment:
The QList.clear() method calls the destructors of every element of the list. At least one of your shared pointers seems not to be initialized correctly. If you need more info, please paste the code that puts stuff into _sections.
Edit Regarding the exception:
As I said the problem is most likely with the shared pointers not being set to anything interesting. When the SP gets destroyed it calls the destructor of its content, which must exist, otherwise it throws a read access violation, which would explain the symptoms.
This what you showed should work. Your problem is in some other place.
This kind of problems might be caused by many different mistakes, like: bad static_cast or bad c-style cast, break in binary compatibility when you are using dynamic libraries, write outside of table, problems with compiler cache (this happens is quite often so cure for that is below).
First what I would try to do:
make clean
qmake
make
This fixes such problem quite often. if i doesn't help you have to find other problems in your code.

Why does the compiler not reserve enough space on the stack?

I have a C++ class Matrix22 with an array and a default constructor:
class Matrix22{
/* something more */
double mat[2][2];
Matrix22(){
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
mat[i][j] = i==j ? 1.0 : 0.0;
}
};
I used it in my program and got a segmentation fault. As the rest was quite difficult and complicated I wrote a simple test routine, that just calls Matrix22(). No more seg fault.
I then ran gdb to debug the problem. If I call the constructor from the separate test routine, gcc reserves some memory for the member mat. I can navigate through the stack and see the return address some bytes after the array.
In the main program the compiler does not reserve enough space. The first element (mat[0][0]) gets written but any futher write just overwrites the next stack frame. I can also verify that as before the constructor the command btreturns a correct backtrace, where after the critical assignment the backtrace is corrupted.
So my question is: Why does in one case the compiler (or the linker?) reserve not enough space for the array, while in the other case that is not happening?
PS: Both "test cases" are compiled with the same compiler and flags and alsolinked against the same object files.
edit:
Here is the "simple" test case that works without seg fault:
void test_Matrix22()
{
Framework::Math::Matrix22 matrix;
}
The code with creates a seg fault is in the class ModuleShaddower (intermixed header and implementation):
class ModuleShaddower{
public:
ModuleShaddower(PVModule& module, const EnvironmentalSetup& setup, const Position& position);
private:
Matrix22 rotMatrix90;
};
ModuleShaddower::ModuleShaddower(PVModule& module, const EnvironmentalSetup& setup, const Position& position)
: module (module), position(position), setup(setup), logger(LoggerFactory::getLoggerInstance())
{
double mat[][2] = {{0, -1},{1, 0}}; // This line will never be reached
rotMatrix90 = Matrix22(mat);
}
As you see, it is quite from within the rest. I will maybe try to extract the problematic code but I think this won't help much.
If your ModuleShaddower contructor code is not getting reached (as per you code comment) then something in your constructor initialization list (related to contructuction of module, possition etc) is causing the problem.
The problem was due to the fact that two object files in different locations had the same name. In the resulting static library, that was created from that object code, sometimes the wrong file gets replaced (both were called Shaddower.o). As I renamed one of the files all went well and no more errors.
I do not know the exact origin of this problem but it is solvable like that.

Segmentation fault calling std::map::clear

I have been struggling with a segmentation fault for months, now I'm here to ask for help.
The segmentation fault appears when I call the following function
void foo(..., std::map<MyClass*, double> & x) {
if ( !x.empty() ) x.clear();
...
}
Class A {
private:
map<MyClass*, double> _N;
public:
void f(...) {
foo(..., _N);
...
}
};
//in main routine, the function is called in a loop
A a;
while(...) {
a.f(...);
}
Using gdb, I tacked the error to the line calling the clear() function, it shows "double free or corruption" error, and the program aborts at calling c++/4.1.2/ext/new_allocator.h:94 delete(__P) which further calls free() from the gnu library /lib64/libc.so.6. But since the elements in the map are not allocated by new, why it still calls free() to clear it up. I would really appreciate your comments. Thank you.
Given that the map is owned by another object it suspiciously sounds that the map-owning object was already deleted when the clear was called.
Also note that names starting with underscore and a capital letter are reserved for the implementation - you aren't allowed to use them.
The code looks fine to me. At least with the limited context you have provided. Usually when I run into issues like this I will simply run the valgrind memcheck tool to find the place were the first "delete" happened. Once you know that, these issues can be pretty simple to solve.

Pointer object in C++

I have a very simple class that looks as follows:
class CHeader
{
public:
CHeader();
~CHeader();
void SetCommand( const unsigned char cmd );
void SetFlag( const unsigned char flag );
public:
unsigned char iHeader[32];
};
void CHeader::SetCommand( const unsigned char cmd )
{
iHeader[0] = cmd;
}
void CHeader::SetFlag( const unsigned char flag )
{
iHeader[1] = flag;
}
Then, I have a method which takes a pointer to CHeader as input and looks
as follows:
void updateHeader(CHeader *Hdr)
{
unsigned char cmd = 'A';
unsigned char flag = 'B';
Hdr->SetCommand(cmd);
Hdr->SetFlag(flag);
...
}
Basically, this method simply sets some array values to a certain value.
Afterwards, I create then a pointer to an object of class CHeader and pass it to
the updateHeader function:
CHeader* hdr = new CHeader();
updateHeader(hdr);
In doing this, the program crashes as soon as it executes the Hdr->SetCommand(cmd)
line. Anyone sees the problem, any input would be really appreciated
When you run into a crash, act like a crime investigator: investigate the crime scene.
what is the information you get from your environment (access violation? any debug messages? what does the memory at *Hdr look like? ...)
Is the passed-in Hdr pointer valid?
Then use logical deduction, e.g.:
the dereferencing of Hdr causes an access violation
=> passed in Hdr points to invalid memory
=> either memory wasn't valid to start with (wrong pointer passed in), or memory was invalidated (object was deleted before passing in the pointer, or someone painted over the memory)
...
It's probably SEGFAULTing. Check the pointers.
After
your adding some source code
your comment that the thing runs on another machine
the fact that you use the term 'flag' and 'cmd' and some very small datatypes
making me assume the target machine is quite limited in capacity, I suggest testing the result of the new CHeader for validity: if the system runs out of resources, the resulting pointer will not refer to valid memory.
There is nothing wrong with the code you've provided.
Are you sure the pointer you've created is the same same address once you enter the 'updateHeader' function? Just to be sure, after new() note the address, fill the memory, sizeof(CHeader), with something you know is unique like 0XDEAD, then trace into the updateHeader function, making sure everything is equal.
Other than that, I wonder if it is an alignment issues. I know you're using 8 bit values, but try changing your array to unsigned ints or longs and see if you get the same issue. What architecture are you running this on?
Your code looks fine. The only potential issue I can see is that you have declared a CHeader constructor and destructor in your class, but do not show the implementation of either. I guess you have just omitted to show these, else the linker should have complained (if I duplicate this project in VC++6 it comes up with an 'unresolved external' error for the constructor. It should also have shown the same error for the destructor if you had a... delete hdr; ...statement in your code).
But it is actually not necessary to have an implementation for every method declared in a class unless the methods are actually going to get called (any unimplemented methods are simply ignored by the compiler/linker if never called). Of course, in the case of an object one of the constructor(s) has to be called when the object is instantiated - which is the reason the compiler will create a default constructor for you if you omit to add any constructors to your class. But it will be a serious error for your compiler to compile/link the above code without the implementation of your declared constructor, so I will really be surprised if this is the reason for your problem.
But the symptoms you describe definitely sounds like the 'hdr' pointer you are passing to the updateHeader function is invalid. The reason being that the 1st time you are dereferencing this pointer after the updateHeader function call is in the... Hdr->SetCommand(cmd); ...call (which you say crashes).
I can only think of 2 possible scenarios for this invalid pointer:
a.) You have some problem with your heap and the allocation of memory with the 'new' operator failed on creation of the 'hdr' object. Maybe you have insufficient heap space. On some embedded environments you may also need to provide 'custom' versions of the 'new' and 'delete' operator. The easiest way to check this (and you should always do) is to check the validity of the pointer after the allocation:
CHeader* hdr = new CHeader();
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
The normal behaviour when 'new' fails should actually be to throw an exception - so the following code will cater for that as well:
try{
CHeader* hdr = new CHeader();
} catch(...) {
//handle or throw specific exception i.e. AfxThrowMemoryException() for MFC
}
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
}
b.) You are using some older (possibly 16 bit and/or embedded) environment, where you may need to use a FAR pointer (which includes the SEGMENT address) for objects created on the heap.
I suspect that you will need to provide more details of your environment plus compiler to get any useful feedback on this problem.

Possible memory leak?

Okay, so I have two classes, call them A and B--in that order in the code. Class B instantiates class A as an array, and class B also has an error message char* variable, which class A must set in the event of an error. I created a third class with a pure virtual function to set the errorMessage variable in B, then made B a child of that third class. Class A creates a pointer to the third class, call it C--when B initializes the array of A objects, it loops through them and invokes a function in A to set A's pointer to C-- it passes "this" to that function, and then A sets the pointer to C to "this," and since C is B's parent, A can set C->errorMessage (I had to do all this because A and B couldn't simultaneously be aware of each other at compile time).
Anyways it works fine, however, and when I pass command line parameters to main(int,char**), it works unless I pass seven, eight, or more than twelve parameters to it... I narrowed it down (through commenting out lines) to the line of code, in A, which sets the pointer to C, to the value passed to it by B. This made no sense to me... I suspected a memory leak or something, but it seems wrong and I have no idea how to fix it... Also I don't get why specifically seven, eight, and more than twelve arguments don't work, 1-6 and 9-12 work fine.
Here is my code (stripped down)--
//class C
class errorContainer{
public:
virtual ~errorContainer(){ }
virtual void reportError(int,char*)=0;
};
//Class A
class switchObject{
void reportError(int,char*);
errorContainer* errorReference;
public:
void bindErrorContainer(errorContainer*);
};
//Class A member function definitions
void switchObject::reportError(int errorCode,char* errorMessage){
errorReference->reportError(errorCode,errorMessage);
}
void switchObject::bindErrorContainer(errorContainer* newReference){
errorReference=newReference; //commenting out this line fixes the problem
}
//Class B
class switchSystem: public errorContainer{
int errorCode;
char* errorMessage;
public:
switchSystem(int); //MUST specify number of switches in this system.
void reportError(int,char*);
int errCode();
char* errMessage();
switchObject* switchList;
};
//Class B member function definitions
switchSystem::switchSystem(int swLimit){
int i;
switchList=new (nothrow) switchObject[swLimit];
for(i=0;i<swLimit;i++){
switchList[i].bindErrorContainer(this);
}
errorCode=0;
errorMessage="No errors.";
}
void switchSystem::reportError(int reportErrorCode,char* reportErrorMessage){
int len=0,i;
errorCode=reportErrorCode;
if(errorMessage){
delete[] errorMessage;
}
while(reportErrorMessage[len]!='\0'){
len++;
}
errorMessage=new char[len];
for(i=0;i<=len;i++){
errorMessage[i]=reportErrorMessage[i];
}
}
int switchSystem::errCode(){
return errorCode;
}
char* switchSystem::errMessage(){
return errorMessage;
}
Anyone know what I've done wrong here?
It's bugging the crap out of me... I can't seem to fix it.
---EDIT---
okay, I have it set up the way I do so that I can use it like this in main()
int main(int argc,char** argv){
switchSystem sw (2)
sw.switchList[0].argumentCount=2;
sw.switchList[1].argumentCount=0;
sw.switchList[0].identifier="a";
sw.switchList[1].identifier="switch";
sw.init(argc,argv);
if(sw.errCode()>0){
cout<< "Error "<< sw.errCode()<< ": "<< sw.errMessage()<< endl;
}
}
this program is supposed to read the command line arguments and handle user defined "switches"--like how most command line programs handle switches, but instead of testing for all of them at the beginning of main I wanted to try to write a class and some functions to do it for me--create a switchSystem object with the number of switches, set their identifiers, whether or not they take arguments, and then pass the command line arguments to "init()" to sort it out. Then test like, if(sw.isSet("switch")){ ... } etc.
It seems scary that you:
Mix dynamic memory with static string constants ("No errors.") in the same pointer.
Use an explicit while-loop to compute the string's length; have you not heard of strlen()?
Use such low-level C-like string processing, for no good reason ... What's wrong with std::string?
Don't properly account for the terminating '\0' in the string, when allocating space for it and copying it. The length is also not stored, leaving the resulting char array rather difficult to interpret.
reportError() should be declared virtual in switchSystem, as it is in errorContainer.
char* should instead be std::string to avoid all of that needless work.
Is there some reason that you can't use an std::vector<switchObject> instead of new[]?
You shouldn't delete[] errorMessage when it points to a static literal string. This leads to undefined behavior. (Translation: Bad Thing(TM).)
Why are you iteratively counting and copying the contents of a char*? This is begging for trouble. You're not doing anything to protect yourself from harm.
Why must switchObject pass a string to switchSystem? Wouldn't it be better to simply return an error code or throw some class derived from std::exception? Or perhaps it should send a string to a global logging facility?
I think perhaps you should rethink your design instead of trying to fix this.
All of the above message contains really good advice, unless this is homework and you can't use STL I'd recommend that you follow them, your problems will be much less.
For example in this snippet
errorMessage=new char[len];
for(i=0;i<=len;i++){
errorMessage[i]=reportErrorMessage[i];
}
You have allocated len bytes, but you are writing to len+1 bytes, you have not allocated memory for the null terminator '\0', overwriting memory lead to nasty bugs that are difficult to trackdown.
I think the memory leak is your minor cocnern in here. You better throw this code and start over again with a new approach. This is a mess.