I know what the error means and I know why it's throwing the error. However I do not understand as to how to resolve it. I have already read the other answers here on StackOverflow, which mostly tell what the error means.
I basically loop through elements, let the elements do something and then at the very end (outside of the loop), at the bottom of my method I use:
void someMethod()
{
for (Wagon& wagon: wagons)
{
//some code
}
wagons.erase(std::remove_if(wagons.begin(), wagons.end(), [](const Wagon& wagon) { return !wagon.active; }), wagons.end());
}
The second iteration it throws exception: std::out_of_range at memory location.
Basically what I am trying to do is remove inactive wagons, so they do not get iterated through the second time it calls the method which loops through the wagons.
Related
Currently, there is one exception thrown from program written by C++, and running under windows.
here is the min dump information in the logs.
08/12/15 04:37:19 I New Information for UID 2d936a, FloorLoc F1505
08/12/15 04:37:19 E >>>>> EXCEPTION: Access Violation while trying to read address 20203567
[Fault address: 004AF945 01:000AE945 C:\Program Files (x86)\MySystems\WPR.exe 00400000] <<<<<
Call stack:
Load addr Address Frame Logical addr Module
00400000 004AF945 0588F8CC 0001:000AE945 C:\Program Files (x86)\MySystems\WPR.exe
00400000 004A89A4 0588FAEC 0001:000A79A4 C:\Program Files (x86)\MySystems\WPR.exe
According to the logical addr and .map file, I can find the codes where this exception thrown.
if (TempMSE->m_elem == NULL)
{
TempMSE->m_elem = new Element(element);
TempMSE->m_elem->SetLocation(FloorLoc);
LoggerInfo("New Information for UID %x, FloorLoc %s", Id, FloorLoc.ToString(buf));
}
TempMSE->m_elem->SetValue0(CIN_0, 0); // this exception is thrown here!!! through logical address 0001:000AE945
It seems that the m_elem gets one address from new operator, and there is NO exception for SetLocation function calling. Also the following log output correctly.
Why there is one exception thrown from SetValue0? Here is function SetValue0
void SetValue0(INDEX idx, DWORD val)
{
if (idx >= 0 && idx < MAX_INDEX){
if(val != m_Info[idx])
{
m_Info[idx] = val;
}
}
}
The m_Info is one array variable in the Element, and its size is MAX_INDEX.
On the other side, the address 0x20203567 seems one readable address, how could it be read violation?
Edit
Add more information here
class Element {
// other function here...
private:
FloorLocation m_FloorLoc;
DWORD m_Info[MAX_INDEX];
bool m_Dirty;
};
Element::Element(const Element& elem) {
m_FloorLoc = elem.m_FloorLoc;
for (int i = 0; i < MAX_INDEX; ++i)
m_Info[i] = elem.m_Info[i];
m_Dirty = elem.m_Dirty;
}
class FloorLocation {
// other function here...
private:
FloorId m_floorloc;
};
FloorLocation::FloorLocation( const FloorLocation& loc )
{
memset(&m_floorloc, ' ', 8); // space filled
if(loc.m_floorloc.id[0] != 0)
{
memcpy(m_floorloc.id, loc.m_floorloc.id, 8);
// eliminate nulls
for(int ndx=0; ndx < 8; ndx++)
{
if(m_floorloc.id[ndx] == 0)
m_floorloc.id[ndx]=' ';
}
}
}
typedef struct {
char id[8];
} FloorId;
These kinds of questions are a little hard to answer. I gave some ideas in comments, which I'll elaborate on here. Here are the kinds of things I look for when I have these sorts of crash logs with no other leads.
An access violation on read at that location suggests one of the following:
TempMSE is not a valid pointer, and the exception is thrown when attempting to get m_elem from it;
TempMSE->m_elem is not valid, and the exception is thrown inside SetValue0 when attempting to test the value of m_Info[idx].
In the latter case, this could occur if you delete TempMSE->m_elem somewhere but don't set it to NULL. If another thread is responsible for that delete, perhaps you have a race condition here where it's about to be set to NULL, but this code is executed first.
Another possibility is that either TempMSE or TempMSE->m_elem get corrupted somewhere along the way. This could be the result of a buffer overrun inside TempMSE (if you have arrays), or basically any sort of undefined behaviour that occurs near these pointers in memory. If TempMSE is on the stack, then look for any potential trouble there.
I don't want to fill this answer with other kinds of speculation (like heap corruption), but hopefully it gives you some avenues to try. The basic list of common culprits is this:
coding error (not initialising or resetting a value)
threading issues, race conditions...
undefined behaviour or overruns trashing data
Good luck!
I can't say what is actually wrong, but I would disassemble the code at 0x004AF945 - and several instructions before, and try to understand what part of the failing function that is.
As pointed out in one of the comments, the address that the fault happens at is suspiciously looking like 'C# ', which makes me think that somewhere a string is overflowing somewhere...
This is just a guess, but I suspect TempMSE->m_elem is what contains the value 0x20203567, and thus is NOT NULL when it tries to access it, meaning no logging is performed. [Obviously this is based on what code you have shown so far, and if there is logging before/after that show this is not the case, my second guess is that m_info is somehow wrong...
I have recently made some modifications to my program and am now getting a lot of bad_alloc and out_of_range exceptions. I'm also using the latest boost-trunk version as I can't use 1.55 (I'm using VC++12 with boost-serialization).
Since I can't go back to a previous version with the old boost I can't just go through everything step-by-step to find the problem.
I'm not used to receiving these exceptions so I don't really know how to go about finding the cause. Here is one of the lines which causes an error (the location of the exception changes):
// userDefinedFile.cpp:
//
// colonySequence is std::list<std::unique_ptr<UserDefClass>>
// allocated_cells is std::vector<std::unique_ptr<UserDefClass>>
colonySequence.emplace_front(
new Colony(allocated_cells.begin(), allocated_cells.end())
); // this causes the error
Output:
HEAP[EDIN.exe]: HEAP: Free Heap block 7068430 modified at 706849c
after it was freed EDIN.exe has triggered a breakpoint.
Further up the stack in <vector> I am seeing this:
template<class _Iter>
void _Construct(_Iter _First, _Iter _Last, forward_iterator_tag)
{ // initialize with [_First, _Last), forward iterators
if (_Buy(_STD distance(_First, _Last))) // ERROR HERE
{ // nonzero, fill it
_TRY_BEGIN
this->_Mylast = _Ucopy(_First, _Last, this->_Myfirst);
_CATCH_ALL
_Tidy();
_RERAISE;
_CATCH_END
}
}
The value returned by _STD distance(_First, _Last) is large (116697808) and appears to cause the error, but the size of allocated_cells is only 46, so I don't understand why this is happening.
This doesn't seem like a symptom of a memory leak to me. How would you go about getting to the cause of this? What sort of code would you expect to generate this kind of error?
Here is the Colony constructor:
//Construct a colony with a sequence of cells
template <typename CellSptrIt>
Colony::Colony(CellSptrIt const begin, CellSptrIt const end) :
sector(&(*begin)->Sector()),
cellSequence(begin,end),
bounds(Colony::Bounds(begin,end))
{}
CellSptrIt is an iterator to a container of CellSptr objects, which are themselves a typedef for std::shared_ptr<Cell>. Cell is a user defined object, although since the constructor is not involved in the error I suspect it's not relevant. Cell.Sector() returns a reference to an object which describes the region of the cell, and the sector(&(*begin)->Sector()) therefore simply copies the sector value from the cell to the colony (a cell and a colony must belong to the same sector).
I was getting bad_alloc while doing serialization once because I was forgetting to close the output stream before reading it back in.
I'm currently learning C++ and practicing my Knowledge by implementing an simple AddressBook Application. I started with an Entry class and an AddressBook class which implements a STL Map to access the entries by the last names of the persons. Now I arrived at the following code:
Entry AddressBook::get_by_last_name(string last_name){
if(this->addr_map.count(last_name) != 0){
//What can I do here?
} else {
return addr_map[last_name];
}
In Scripting Languages I would just return something like -1, Error Message(A List in Python) to indicate that the Function failed. I don't want throw an exception, because it's part of the application logic. The Calling Class should be able to react to the request by printing something on the console or opening a Message Box. Now I thought about implementing the Scripting Languae Approach in C++ by introducing some kind of an Invalid State to the Class Entry. But isn't that bad practice in C++? Could it be that my whole class design is just not appropriate? I appreciate any help. Please keep in mind that I'm still learning C++.
Some quick notes about your code:
if(this->addr_map.count(last_name) != 0){
//What can I do here?
You probably wanted it the other way:
if(this->addr_map.count(last_name) == 0){
//handle error
But your real problem lies here:
return addr_map[last_name];
Two things to note here:
The operator[] for map can do 2 things: If the element exists, it returns it; If the element doesn't exist, it creaets a new (key,value) pair with the specified key and value's default constructor. Probably not what you wanted. However, if your if statement from before would have been the right way, then the latter would never happen because we would knowthe key exists before hand.
In calling count() before, you effectively tell map to try and find the element. By calling operator[], you are telling map to find it again. So, you're doing twice the work to retrieve a single value.
A better (faster) way to do this involves iterators, and the find method:
YourMap::iterator it = addr_map.find(last_name); //find the element (once)
if (it == addr_map.end()) //element not found
{
//handle error
}
return *it.second; //return element
Now, back to the problem at hand. What to do if last_name is not found?
As other answers noted:
Simplest solution would be to return a pointer (NULL if not found)
Use boost::optional.
Simply return the YourMap::iterator but it seems that you are trying to "hide" the map from the user of AddressBook so that's probably a bad idea.
throw an exception. But wait, now you'll have to first check that calling this method is 'safe' (or handle the exception when appropriate). This check requires a boolean method like lastNameExists which would have to be called before calling get_by_last_name. Of course then we'er back to square 1. We're performing 2 find operations to retrieve a single value. It's safe, but if you're doing A LOT of calls to get_by_last_name then this is potentially a good place to optimize with a different solution (besides, arguably the exception is not very constructive: What's wrong with searching for something that isn't there, huh?).
Create a dummy member for Entryindicating that is not a real Entry but that is very poor design (unmanageable, counter intuitive, wasteful - you name it).
As you can see, the first 2 solutions are by far preferable.
One dead-simple option is to change the return type to Entry* (or const Entry*) and then return either the address of the Entry if found, or NULL if not.
If you use Boost, you could return a boost::optional<Entry>, in which case your success code would be the same, but on not-found you'd say return boost::none. This is fancier, but does about the same thing as using a pointer return type.
Throwing an exception is definitely the 'correct' C++ thing to do, based on your function return type.
You might want a function like this to help you, though:
bool AddressBook::lastNameExists(const string &last_name)
{
return addr_map.count(last_name) > 0;
}
Note that your current code returns the entry 'by value' so modifying the returned entry won't update the map. Not sure if this is by accident or design...
Other answers have given various approaches, most of them valid. I didn't see this one yet:
You could add a second parameter with a default value:
Entry AddressBook::get_by_last_name(string last_name, const Entry& default_value){
if(this->addr_map.count(last_name) == 0){
return default_value;
} else {
return addr_map[last_name];
}
In this particular instance, there might not be a sensible default value for a non-existing last name, but in many situations there is.
In C++ you have several ways of signalling that an issue happened in your function.
You can return a special value which the calling code will recognize as an invalid value. This can be a NULL pointer if the function should return a pointer, or a negative value if your function returns an index in an array, or, in the case of a custom class (e.g. your Entry class) you can define a special Entry::invalid value or something similar that can be detected by the calling function.
Your calling code could look like
if ( entryInstance->get_by_last_name("foobar") != Entry::invalid)
{
// here goes the code for the case where the name is valid
} else {
// here goes the code for the case where the name is invalid
}
On the other hand you can use the C++ exceptions mechanism and make your function throw an exception. For this youcan create your own exception class (or use one defined in the standard library, deriving from std::exception). Your function will throw the exception and your calling code will have to catch it with a try...catch statement.
try
{
entryInstance->get_by_last_name("foobar")
}
catch (Exception e)
{
// here goes the code for the case where the name is invalid
}
// here goes the code for the case where the name is valid
Apart from the fact that you could have more than one entry per surname.
Eliminate the getter, and you've solved the problem, or at least shifted it elsewhere.
Tell the AddressBook to display people with given surnames. If there aren't any it can do nothing.
AddressBookRenderer renderer;
AddressBook contacts;
contacts.renderSurnames("smith", renderer);
contacts.renderCompletions("sm", renderer);
//etc
You can do what std::map (and the other containers do).
You return an iterator from your search function.
If the search does not find a value that is useful return an iterator to end().
class AddressBook
{
typedef <Your Container Type> Container;
public:
typedef Container::iterator iterator;
iterator get_by_last_name(std::string const& lastName) {return addr_map.find[lastName];}
iterator end() {return addr_map.end();}
};
Your address book is a container like object.
Not finding an item in a search is likely to happen but it does not have enough context to incorporate error handling code (As the address book could be used from lots of places and each place would have different error handling ideas).
So you must move the test for not found state out of your address book.
just like "Python" we return a marker. In C++ this is usually an iterator to end() which the calling code can check and take the appropriate action.
AddressBook& ab = getAddressBookRef();
AddressBook::iterator find = ab.get_by_last_name("cpp_hobbyist");
if (find != ab.end())
{
Entity& person *find; // Here you have a reference to your entity.
// you can now manipulate as you want.
}
else
{
// Display appropriate error message
}
I'm having problems creating a tmx map from string input.
bool LevelManager::initLevel(int currentLevel)
{
const char* map;
try {
map = LevelManager::getLevel(currentLevel);
} catch (int) {
throw 1;
}
if(map != NULL){
CCLog("%s", map);
tileMap = CCTMXTiledMap::create(map);
tileMap->setAnchorPoint(ccp(0,0));
tileMap->setPosition(ccp(15,20));
this->addChild(tileMap, 5);
backgoundLayer = tileMap->layerNamed("Background");
} else {
throw 1;
}
return true;
}
Thats my code.
It is very unstable. Most of the times it crashes and sometimes it doesn't.
I'm loading my map from the string map. Wich is a const *char.
My map is named Level1.tmx and when i load the map like this: tileMap = CCTMXTiledMap::create("Level1.tmx"); it always works and never crashes.
And i know for a fact that the value of map is Level1.tmx because i log it in the line before the load.
When it crashes the log outputs this: (lldb)
and on the line tileMap->setAnchorPoint(ccp(0,0)); it says "Thread 1: EXC_BAD_ACCESS (code=2, adress=0x0)
Does anyone know why this happens and how to fix it?
Many thanks.
Ps: i'm using xcode, the latest cocos2d-x release and the iPhone simulator
Edit:
Using breakpoints i checked where things go bad while loading the tilemap.
on the line tileMap = CCTMXTiledMap::create(map);
my variable map is still fine
but on line tileMap->setAnchorPoint(ccp(0,0));
it is suddenly corrupted (most of the time)
It sounds like you're returning a char* string created on the stack, which means the memory may or may not be corrupted, depending on circumstances, moon phases, and what not.
So the question is: How is getLevel defined and what does it do (post the code)?
If you do something like this:
const char* LevelManager::getLevel(int level)
{
char* levelName = "default.tmx";
return levelName;
}
…then that's going to be the culprit. The levelName variable is created on the stack, no memory (on the heap) is allocated for it. The levelName variable and the memory it points to become invalid as soon as the method returns.
Hence when the method leaves this area of memory where levelName points to can be allocated by other parts of the program or other method's stack memory. Whatever is in that area of memory may still be the string, or it may be (partially) overridden by other bits and bytes.
PS: Your exception handling code is …. well it shows a lack of understanding what exception handling does, how to use it and especially when. I hope these are just remnants of trying to get to the bottom of the issue, otherwise get rid of it. I recommend reading a tutorial and introductions on C++ exception handling if you want to continue to use exceptions. Especially something like (map != NULL) should be an assertion, not an exception.
I fixed it.
const char* was to blame.
When returning my map as a char * it worked flawless.
const char *levelFileName = level.attribute("file").value();
char *levelChar = new char[strlen(levelFileName) + 1];
std:: strcpy (levelChar, levelFileName);
return levelChar;
Thats how i now return the map.
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.