I was working on a C++ project with visual studio 2010 and everything was fine but when i tried to run my program with xcode 4 it raises Bas_Access exception. I think it's because of a memory leak but I'm not sure about how to solve the problem.
I have the following function:
// Search is my class with x and y as members and here's is a constructor
// that I cretae in my Search.cpp class
Search& Search::operator=( const Search& search )
{
if(this != &search)
{
x = search.x;
y = search.y;
}
return *this;
}
And here is how my function is called:
Search searchStart(0,0);
//I created my tempSearch and initialized it with the start Search element
Search tempSearch(searchStart);
//bestSolution is a function that calculates the best neighbour node around the searchStart node, it returns a Search element. And stores it in a list in storage.
Search * tempCurrent=searchStart.bestSolution(&storage);
//Here I call my function
tempSearch=*tempCurrent;
I'm simply creating a new Search element from an existing element but it gives me exception at
x=search.x;
It works perfectly with visual studio.
EDIT:
I just added the code where my function is called. Excuse me for not being able to provide the full code because it's really long.
EDIT:
Here's my bestSolution function:
Search * searchNode::Search::bestSolution(Storage *storage )
{
//listResult is a type defined as std::list<Search *> listResult.
listResult::iterator it, it1;
listResult tempList;
//I've initialized the result element at (0,0) because it was creating problems
// if uninitialized
Search *result=new Search(0,0);
//openList is a simple list of Search elements
if(!storage->openList.empty()){
for(it=storage->openList.begin();it!=storage->openList.end();it++)
{
tempList.push_back((*it));
}
tempList.reverse();
it1=tempList.begin();
// getDistanceCost is a function that calculates the heuristic distance
// between two points and works fine
int fCost=(*it1)->getDistanceCost();
for(it1=storage->openList.begin();it1!=storage->openList.end();it1++)
{
if((*it1)->getDistanceCost()<=fCost){
fCost=(*it1)->getDistanceCost();
result=(*it1);
}
}
}
return result;
}
My guess is that bestSolution is returning a pointer to an object allocated on stack. Now when you try to tempSearch=*tempCurrent you are trying to copy values into this invalid pointer which causes the undefined behavior.
EDIT
Looking at the implementation of the bestSolution method, I assume listResult contains Search* as its nodes as you are doing result=(*it1);. It looks like the Search object to which the list has a pointer was deleted after it was inserted into the list. So what you have in the list is an invaid pointer. If you try to copy anything to the memory pointed by this invalid pointer, your program will behave unpredictably.
Given the information you provided it is certain that the problem lies in
Search * tempCurrent=searchStart.bestSolution(&storage);
It must return some invalid pointer (perhaps NULL).
This invalid pointer is then passed as the search parameter (more precisely as &search) to your Search::operator= which then tries to access the x (and later the y) member of this invalid pointer (search.x and search.y).
Related
is there a way to implement bsearch() to find multiple instances of key.
for example: (obj*)bsearch(key=r,arr,elements,sizeof(obj),(int(*)(const void*, const void*)bcompare);
The code I currently wrote only finds the first instance and cannot proceed past the first found due to how it works.
getline(target,81);
if(strcmp(target,"exit") == 0 || strcmp(target, "") == 0) break;
p = (Info*)bsearch(target,list,num,sizeof(Info),(int(*)(const void*, const void*))bcompare);
int foundIndex = (int)(p-list);
if(!p){
err_dis1_win();
clrscr();
}
else{
display_record(p);
cout << "\n\n found at index " << foundIndex << "\n";
getch();
clrscr();
}
Variables:
p - is a pointer to object of class Info
target - arr of char
list - arr of obj
foundIndex - index of element found
Info - derived class from base class
**compare function
int bcompare(char *a,Info *b){
return(strncmpi(a, b -> get_name(), strlen(a)));
}
I cannot use other methods such as std::find or writing my own binary search function and have to use bsearch()
I have tried loops inside the else block, and the compare function using the varible foundIndex, as well as using a while loop on the return value looping through the obj list arr. Is there a way to start at a specific index. I appreciate any help. I am not looking for code but a general push in the right direction. Thank you.
Caveat - The current code compiles and runs as expected however, the functionality that I want, cannot be figured out by myself. Google and search on Stackoverflow has not produced an related issue.
Since bsearch() returns only one item, I interpret "find multiple instances of key" as "find the first instance of a key". The caller can then step forward through the array from that item to process each item matching the key, until it reaches the end or reaches an item that does not match.
If you must use the standard library's bsearch() function and persuade it to find the first item matching a given key, then all you really have to work with is the comparison function you present. bsearch() will return an item that matches the key according to that function, but if more than one item matches then there is no guarantee which one will be returned. You must ensure, then, that only the item you want matches.
You can approach that with an appropriate implementation of the comparison function, but there is a significant problem. The function will in some cases need to evaluate the item preceding the one specified to it, but it must not attempt to examine an item preceding the array's first. bsearch() does not itself convey any information about the array bounds to the comparison function.
There are at least two possible solutions, neither of them stellar.
Store the array lower bound in some well-known location that the function can access. For example, if the comparison function is a static member function, then maybe you would use a static variable of its class. But that is not thread-safe. You could do something similar with thread-local variables, but even then it's ugly. Either way, you have to be sure to set that variable appropriately before you call bsearch(), and that's ugly, too.
OR
Ensure that you never bsearch() for the first item. One way you could do that would be by checking preliminarily whether the first item matches (but not via the comparison function), and using it directly instead of calling bsearch() in the event that it does match. I'd wrap that in a method, myself, and if you must not do so then requiring that such a calling discipline be employed manually is also ugly.
Having chosen one of the above, you can implement a comparison function that looks at the previous item's key in addition to the specified item's. Something along these lines (which assumes the second alternative):
struct my_item {
int key;
void *data;
};
// bsearch() passes the target item as the first argument, and the one to compare
// to it as the second
int compare_items(const void *to_find, const void *to_check) {
const struct my_item *to_find_item = (const struct my_item *) to_find;
const struct my_item *to_check_item = (const struct my_item *) to_check;
// Check first how the key members are ordered
if (to_find_item->key < to_check_item->key) {
return -1;
} else if (to_find_item->key > to_check_item->key) {
return 1;
} else {
// The key members match, so check whether we're looking at the first
// such item.
const struct my_item *previous_item = to_check_item - 1;
// If the previous item's key does match, then we know the item we're
// looking for is an earlier one than we are presently checking.
return (previous_item->key == to_check_item->key) ? -1 : 0;
}
}
I am trying to emplace_back a locally constructed (inside method) cv::Point3i onto an object variable (declared as std::vector<cv::Point>). Doing so, I get the compile error (not runtime):
memory - No matching constructor for initialization of 'cv::Point_<int>'
Trying the same thing with a Point2i instead (omitting one of the value I need), the compiler throws no error.
Here's the snippet from the .cpp file:
void ObjectDetector::centroids2Dto3D() {
const int* map_ptr = (int*)mapHeight.data;
unsigned long steps[2];
steps[0] = mapHeight.step1(0);
steps[1] = mapHeight.step1(1);
for (std::vector<cv::Point>::iterator it = centroidsXZ.begin(); it != centroidsXZ.end(); it++) {
const int x = (*it).x;
const int z = (*it).y;
int y = map_ptr[steps[0] * x + steps[1] * z];
// MARK: The following line causes the error. Without it, the program compiles fine
centroids.emplace_back(cv::Point3i(x,y,z));
}
}
As I am not the best at debugging C++, I tend to put the fault on my coding, but I cannot find the problem here.
Could someone points me to a solution or a path toward it?
Thanks!
Since you're inserting into the vector objects of type cv::Point3i, then the type of centroids should be: std::vector<cv::Point3i>.
Also, you're calling emplace_back wrong. Its arguments should be the arguments to forward to the constructor of the Point3i, i.e.: centroids.emplace_back(x,y,z);
Using emplace_back will avoid the extra copy or move operation required when using push_back. You can find more details here.
While writing code for my assignment, I have stuck on one strange behavior. The code is big, so while it is not necessary, I won't post it.
The thing is while I was trying to delete an object from the vector, I had a segmentation fault. While trying to debug it myself, I have found this:
If I execute my code with the following snippet, I have my vector empty and then segmentation fault on the second line (since vector is empty).
cout << this->adjacencyList.empty() << endl; // yeah, I'm working with graph
cout << *(this->adjacencyList[0]) << endl; // list has pointers
However, when I delete the second line, it shows that vector is not empty and then proceeds.
The guard for empty vectors cannot hold it and segmentation fault comes.
Do you have any ideas on this behavior? If the point is still vague, I can post my full code as an edit.
Thanks in advance.
EDIT:
For the one who was asking "a little more".
void Node :: removeEdge (string destination) // removes an edge; edge is a class that contains a pointer to another node and its weight
{
bool deleted = false;
cout << *this << endl; // output stream operator is overloaded for node class and is working properly - shows it's label and edges - no error for an edge
cout << this->adjacencyList.empty() << endl;
// cout << *(this->adjacencyList[0]) << endl; // output stream operator is overloaded for edge class - error for an edge
if (!this->adjacencyList.empty())
{
for (vector <Edge *> :: iterator itr = this->adjacencyList.begin(); itr != this->adjacencyList.end(); ++itr)
{
if (((*itr)->getAdjacent())->getLabel() == destination) // segfault here
{
Edge *temp = *itr;
this->adjacencyList.erase (itr);
delete temp;
deleted = true;
}
}
}
if (!deleted)
throw EDGE_DOES_NOT_EXIST; // one of exceptions declared in enum somewhere in my code
}
SECOND EDIT:
NOTE: I cannot change headers (they were supplied by assistants), so don't ask me to change.
If you are interested in a full code, you can find here
http://pastebin.com/iCYF6hdP - Exceptions.h - all exceptions
http://pastebin.com/1fcgHGDa - Edge.h - edge class declaration
http://pastebin.com/C2DD6e3D - Edge.cpp - edge class implementation
http://pastebin.com/ZNqQ1iHE - Node.h - node class declaration
http://pastebin.com/kaVtZ3SH - Node.cpp - node class implementation
http://pastebin.com/A7Fwsi4m - Network.h - graph class declaration
http://pastebin.com/02LX0rjw - Network.cpp - graph class implementation
http://pastebin.com/MRMn0Scz - main.cpp - sample main
I would guess, that the pointer stored in the first element of your vector is invalid (perhaps NULL?).
So the segfault doesn't come up in this->adjacencyList[0] but in *(some_invalid_pointer).
Try
Edge* firstEdge = this->adjacencyList[0];
cout << *firstEdge << endl;
to verify this.
EDIT
If the segfault happens in the first statement (the assignment), this means, that either this is invalid or you somehow managed to corrupt memory belonging to the internals of vector. For this to verify, we would have to see all code that deals with your adjacencyList (and I'm not sure if SO people have the time for this task ...)
Note
I've spotted a bug in the removeEdge, which is not directly related to your problem. Within the loop, you use vector::erase to delete the current element. This invalidates all iterators beyond the current one, so theoretically the rest of the loop is the infamous 'undefined behavior'(TM). In this specific case (and supposing a 'normal' standard library), this will not result in a segfault but you might miss some elements:
If you delete the current element, the current iterator (normally simply a pointer) will point to the next element. Then, the loop increment will move it to the element after this one resulting in one element not being checked.
If you have similar bugs in your code in other places, this might well result in memory corruption.
Tip
If you're using Microsoft C++, you can enable checked iterators (see here). These might be able to spot this kind of bugs in your code.
2nd EDIT (in response to code)
You have a serious error in the Node::operator+.
Node &operator+ (Node &l, Node &r) // merges two nodes - for network merging
{
Node newNode (l.label);
// Doing something
return newNode;
}
That means, you're returning a reference to a local variable, never do that :) ...
Note that, since you're using a vector of pointers, which are managed separately and released in the destructor, you cannot simply change the signature to Node operator+(...: in this case, the standard copy constructor would be called, which would simply copy all pointers to the result object. Then, the destructor of the local object would be called which would invalidate all pointers.
To fix this, you should implement a copy constructor on Node which makes real copies of all edges in the adjacency list.
Alternatively, you could use smart pointers (either auto_ptr resp. unique_ptr or shared_ptr) for the list.
Or you change the merge function to something like Node::mergeFrom(Node& node2) instead of overloading the +operator.
Concerning the original problem, you can easily end up working on an invalid Node instance using your current code (so the *this-Pointer would be invalid inside removeEdge)
Whenever I call dominoes.erase() which is of type std::vector<Domino> I get a segmentation fault; even if I hard code the value.
A separate member function calls dominoes.push_back() to load data and I'm able to use pop_back() to remove and return the a domino from the vector, so I know there's data in there. I've got a copy constructor made on the Domino object and that works just fine. I've narrowed it down to dominoes.erase().
Domino::Domino( const Domino &d ) {
left = d.getHighPip();
right = d.getLowPip();
}
Domino DominoCollection::drawDomino( void )
{
int index = random.nextNumber( dominoes.size() );
Domino d( dominoes[index] );
dominoes.erase( dominoes.begin() + index );
return Domino( d );
}
Any help would be greatly appreciated. Thanks!
Try to narrow down the error by removing all unnecessary code (object copy, vector access...). Then if the problem really comes from erase, add guards to be sure the indexes are right. Try again with this code:
#include <cassert>
void DominoCollection::drawDomino( void )
{
assert(dominoes.size() != 0 && "Your vector is empty");
int index = random.nextNumber( dominoes.size() );
assert(index < dominoes.size() && "Buffer overflow...");
dominoes.erase( dominoes.begin() + index );
}
If it still segfaults, the problem comes from the destructor of the class Domino. Look if there is anything fishy there. You can do quick tests by commenting parts of the destructor (or all of it), to know where the problem comes from. Calling erase will call the destructor of Domino.
If the destructor is not implemented, it might be a good idea to implement one with an output in it (on cerr, not cout) to know if it gets there or crashes earlier on. Is Domino a derived class? Does it have any other objects in it or only a composition of primitive types?
Edit
I went through your code quickly: the problem comes from the assignment operator:
Domino & Domino::operator = ( const Domino & d )
{
*this = d;
}
This is NOT how it should be written... I let you debug that as an exercise.
As for why that is the source of the bug: you said erase crashed but not pop_back. The main difference between the two (implementation difference, not the obvious semantic difference) is that erasing causes all the elements to shift after the ones deleted (using the = operator) because std::vector requires the elements to be stored consecutively. Whereas pop just changes the tail pointer and does not alter the rest of the container.
From what you show us, it looks like the int index has a value greater than or equal to dominoes.size(). Otherwise, that code would work just fine.
I'd check what random.NextNumber(dominoes.size()) returns.
Also, this problem could occur if dominoes.size() == 0. In that case, you'd be erasing dominoes.end().
This is a follow-up on a previous question I had ( Complexity of STL max_element ).
I want to basically pop the max element from a set, but I am running into problems.
Here is roughly my code:
set<Object> objectSet;
Object pop_max_element() {
Object obj = *objectSet.rbegin();
set<Object>::iterator i = objectSet.end()--; //this seems terrible
objectSet.erase(i); //*** glibc detected *** free(): invalid pointer
return obj;
}
Earlier I tried objectSet.erase(objectSet.rbegin()); but the compiler complained that there was no matching function (I'm guessing it doesn't like the reverse_iterator). I know there is no checking for an empty set, but it's failing when objectSet.size() >> 0.
You're pretty close, but you're trying to do a little too much in that iterator assignment. You're applying the post-decrement operator to whatever end returns. I'm not really sure what that does, but it's almost certainly not what you want. Assign the result of end to i, and then decrement it to get the last element of the set.
set<Object>::iterator i = objectSet.end();
--i;
Object obj = *i;
objectSet.erase(i);
return obj;
You need to do this:
set<Object> objectSet;
Object pop_max_element() {
Object obj = *objectSet.rbegin();
set<Object>::iterator i = --objectSet.end(); // NOTE: Predecrement; not postdecrement.
objectSet.erase(i); //*** glibc detected *** free(): invalid pointer
return obj;
}
The statement
set<Object>::iterator i = objectSet.end()--;
means 'assign end() to i then decrement a temporary variable that is about to be thrown away'. In other words it's the same as set<Object>::iterator i = objectSet.end();, and I'm sure you recognise you cannot erase end(), because it points to one past the end. Use something like this instead:
assert(!objectSet.empty()); // check there is something before end
set<Object>::iterator i = objectSet.end();
--i;
objectSet.erase(i);
and that's okay, it's a legitimate way to essentially reproduce .back() for a set.
Also, reverse iterators have a base() member to convert to a normal iterator and I guess you can only erase normal iterators - try objectSet.erase(objectSet.rbegin().base()).