Why does the compiler not reserve enough space on the stack? - c++

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.

Related

Errors with initialization of an unordered_map inside of a class

The error I'm getting is Exception thrown at 0x00007FF77339C476 in VirusSimulator.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
I've gone through my code with Visual Studio's debugger, and it seems like the error is from an attempt to call .size() on a unordered map of class objects.
Specifically, in the implementation of "list":
size_type size() const _NOEXCEPT
{ // return length of sequence
return (this->_Mysize());
}
When stepping through with the debugger and keeping an eye on local variables, I see: this 0xccccccccccccce0c folders={ size=??? }
(folders being the map of class variables)
Just below is a section of int main() where I manually initialize a default folder in each computer's drive's map of folders:
vector<Computer> macs;
for (int i = 0; i < mac_amount; i++)
{
macs.push_back(Computer(OSX)); //Initialize a computer with an operating system
}
for (int i = 0; i < macs.size(); i++)
{
//... Here is some code initializing connections between the computer objects
//and here is the manual insert of folders into the map
macs[i].getDrive()->addFolder("default"); //This used to be in the computers constructor but I moved it out here for testing
}
definition of addFolder:
void Harddrive::addFolder(string name)
{
Folder new_folder;
new_folder.set_name(name);
folders.insert(std::pair<string, Folder>(name, new_folder));
}
Basically, a random computer object then runs a virus that attempts to install itself to every other connected computer object by accessing the list of connections that is has, which contain pointers to the other computer objects.
It then de-references these and attempts to find the default folder on each respective computer's harddrive, but then fails to do so, claiming that the folder is uninitialized?
If any other pieces of my code are needed, then the full code can be found at https://github.com/BananaSky/VirusSimulator/tree/UnstableNetworkAdditions
Most of the code I've already tested for bugs, and that's why I've only posted such a small portion.
Any help is much appreciated!! (But also, it's getting late here and I might be going to sleep soon, so I apologize if I can't respond right away)
--ALSO: Please note that this is just a simulation and that I'm not actually intending to create any form of computer virus.
Here is the section of code where the error occurs (inside Virus.cpp):
vector<int> vulnerableConnectionIPs = installedOn->getNetworkAdapter()->getConnection()->getConnections();
for (int i = 0; i < vulnerableConnectionIPs.size(); i++)
{
Computer* accessRequest = installedOn->getNetworkAdapter()->getConnection()->getConnect(vulnerableConnectionIPs[i])->giveAccess();
if (accessRequest != NULL && accessRequest != installedOn)
{
if (accessRequest->getDrive()->getFolders()) //Error occurs here
{
accessRequest->Install(this, "default"); //Infect if infectable :)
}
else
{
cout << "No folders exist on " << accessRequest->getDrive()->getModel() << endl;
}
}
}
I'm working on replicating this on a smaller scale, and I'll probably get that posted by tomorrow
A memory address of 0xcccccccccccccccc (64-bit) or 0xcccccccc (32-bit) is Visual Studio's way of denoting an uninitialized block of memory. There's also 0xfeeefeee for already free'd and 0x00000000 for a null pointer.
Check that you have actually stored a value in the variable you are trying to access.
The values actually shown from error dialogs may be offset to values close to the above locations, you'll just have to trace through the program.
Your initial description of the error also points to at least trying to de-reference a null pointer.
More code would be helpful.

" malloc error pointer being freed was not allocated " error only in simulator:

When I debug on actual devices, there is no error, but when I use the simulator, Xcode's debugger console displays the following error when running:
malloc: *** error for object 0xaaaaaaaa: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
The error always happens at the same line, which is in the constructor of another class:
Segment *segment = new Segment(0.0,0.0,3.0,1.3,10);
this->segments.push_back(segment); // Malloc error at this line
My Segment class:
class Segment {
private:
float ajc;
float frl;
std::unordered_map<int,int> jgrc;
std::vector<int> lorb;
public:
std::tuple<float,float> getMjt();
float getBuw();
….
Segment(float a, float f,float g, float lo, float u){
……
};
};
On the simulator, regardless of iOS version, the error appears. On devices, regardless of version, there is no error.
I have heard about the rule of 3, but in this case I don't think I need to apply it because the default compiler supplied code should work (unless I'm mistaken). What am I doing wrong, and how can I fix this ? Since there is no error reported on devices, should i ignore it ?
First put a NULL check to avoid the run time error. I tried a pseudo code on VS and it seemed to work. I hope your vector is similar.
Segment *segment = new Segment(0.0, 0.0, 3.0, 1.3, 10);
std::vector<Segment*> vec;
if (NULL != segment)
vec.push_back(segment);
I think there is some problem with your simulator not working fine.
The solution works, but I don't understand why. If someone with more c++ can explain it well, I will mark that as the correct answer.
The following code runs in the constructor of my class that creates the segments:
Segment *segment = new Segment(0.0,0.0,3.0,1.3,10);
this->segments.push_back(segment); // Malloc error at this line
First, I used objects instead of the pointer. Then I moved the code out of the constructor, and instead call it immediately after creating an instance of the class.
Say my class is:
class MyClass{
std::vector<Segment> segments;
}
I do :
MyClass *foo = new MyClass();
foo->createSegments();
Where:
createSegments(){
Segment segment = Segment(0.0,0.0,3.0,1.3,10);
segments.push_back(segment);
}
I'm not very experienced with C++, so I don't know why this works.I also still don't know why the original error only appeared in the simulator.

seg fault after end of function (C++)

I'm having a seg fault: 11 when I run a particular program. I feel like this problem wasn't present before I upgraded my system to Mac OS X 10.9, but it's possible I just overlooked it..
Anyway, my function looks like:
// this applies a warp to the field given, and saves output. simple!
void Apply(string warpName, string fieldName, bool conserve, string outName) {
// get lon, lat dimensions of warp
int noLongs = GetDimension(warpName, 3, "warp");
int noLats = GetDimension(warpName, 2, "warp");
int origNoLongs = noLongs, origNoLats = noLats;
// read in params
vector<double> params = ImportWarpFromNetCDF(warpName);
// rescale field to warp's dimensions, and read in
string tempName = "scaledField";
ReScale(fieldName, tempName, noLongs, noLats);
vector<vector<vector<double> > >inIntensities = ImportFieldFromNetCDF(tempName);
RemoveFile(tempName);
// just enter inIntensities for ref image, and 1 for lambda, to keep objective function happy
ObjectiveFunction objective(inIntensities, inIntensities, conserve, 1, false);
objective.setParameters(params);
// output files
ExportOutputToNetCDF(objective, outName);
cout << "BAH?!" << endl;
}
where the cout line at the end was just checking to see I'd got to the end of the function properly (which I have). Any thoughts on why this would be segfaulting here? I appreciate it might be hard to tell without seeing what the individual function calls do, and so I'll add those if necessary.
It doesn't actually matter too much, as this function is the last thing to be called (so the seg fault doesn't interrupt anything), but I still would rather get to the bottom of it!
The only thing that happens "after" the function are destructor calls. Check all your destructors of local variables. It looks like ObjectiveFunction is the only local variable that's not a primitive or standard library container, so check ObjectiveFunction::~ObjectiveFunction() for potential problems.

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.

Why I am getting a Heap Corruption Error?

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