Segmentation fault when calling vector.erase() - c++

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

Related

Is there any elegant way of iterating through a list whose elements' positions can change?

I am currently running into a disgusting problem. Suppose there is a list aList of objects(whose type we call Object), and I want to iterate through it. Basically, the code would be like this:
for(int i = 0; i < aList.Size(); ++i)
{
aList[i].DoSth();
}
The difficult part here is, the DoSth() method could change the caller's position in the list! So two consequences could occur: first, the iteration might never be able to come to an end; second, some elements might be skipped (the iteration is not necessarily like above, since it might be a linked list). Of course, the first one is the major concern.
The problem must be solved with these constraints:
1) The possibility of doing position-exchanging operations cannot be excluded;
2) The position-exchanging operations can be delayed until the iteration finishes, if necessary and doable;
3) Since it happens quite often, the iteration can be modified only minimally (so actions like creating a copy of the list is not recommended).
The language I'm using is C++, but I think there are similar problems in JAVA and C#, etc.
The following are what I've tried:
a) Try forbidding the position-exchanging operations during the iteration. However, that involves too many client code files and it's just not practical to find and modify all of them.
b) Modify every single method(e.g., Method()) of Object that can change the position of itself and will be called by DoSth() directly or indirectly, in this way: first we can know that aList is doing the iteration, and we'll treat Method() accordingly. If the iteration is in progress, then we delay what Method() wants to do; otherwise, it does what it wants to right now. The question here is: what is the best (easy-to-use, yet efficient enough) way of delaying a function call here? The parameters of Method() could be rather complex. Moreover, this approach will involve quite a few functions, too!
c) Try modifying the iteration process. The real situation I encounter here is quite complex because it involves two layers of iterations: the first of them is a plain array iteration, while the second is a typical linked list iteration lying in a recursive function. The best I can do about the second layer of iteration for now, is to limit its iteration times and prevent the same element from being iterated more than once.
So I guess there could be some better way to tackle this problem? Maybe some awesome data structure will help?
Your question is a little light on detail, but from what you have written it seems that you are making the mistake of mixing concerns.
It is likely that your object can perform some action that causes it to either continue to exist or not. The decision that it should no longer exist is a separate concern to that of actually storing it in a container.
So let's split those concerns out:
#include <vector>
enum class ActionResult {
Dies,
Lives,
};
struct Object
{
ActionResult performAction();
};
using Container = std::vector<Object>;
void actions(Container& cont)
{
for (auto first = begin(cont), last = end(cont)
; first != last
; )
{
auto result = first->performAction();
switch(result)
{
case ActionResult::Dies:
first = cont.erase(first); // object wants to die so remove it
break;
case ActionResult::Lives: // object wants to live to continue
++first;
break;
}
}
}
If there are indeed only two results of the operation, lives and dies, then we could express this iteration idiomatically:
#include <algorithm>
// ...
void actions(Container& cont)
{
auto actionResultsInDeath = [](Object& o)
{
auto result = o.performAction();
return result == ActionResult::Dies;
};
cont.erase(remove_if(begin(cont), end(cont),
actionResultsInDeath),
end(cont));
}
Well, problem solved, at least in regard to the situation I'm interested in right now. In my situation, aList is really a linked list and the Object elements are accessed through pointers. If the size of aList is relatively small, then we have an elegant solution just like this:
Object::DoSthBig()
{
Object* pNext = GetNext();
if(pNext)
pNext->DoSthBig();
DoSth();
}
This has the underlying hypothesis that each pNext keeps being valid during the process. But if the element-deletion operation has already been dealt with discreetly, then everything is fine.
Of course, this is a very special example and is unable to be applied to other situations.

concurrent_vector invalid data

using : VC++ 2013
concurrency::concurrent_vector<datanode*> dtnodelst
Occasionally when I do dtnodelst->at(i) .... I am getting an invalid address (0XCDCD.. ofc)
which shouldn't be the case cause after I do push back, I never delete or remove any of the itms ( even if I delete it should have returned the deleted old address... but I am not ever deleting so that is not even the case )
dtnodelst itm = new dtnodelst ();
....
dtnodelst->push_back(itm);
any ideas on what might be happening ?
p.s. I am using windows thread pool. some times .. I can do 8million inserts and find and everything goes fine .... but sometimes even 200 inserts and finds will fail. I am kind of lost. any help would be awesomely appreciated!!
thanks and best regards
actual code as an fyi
p.s. am I missing something or is it pain in the ass to past code with proper formatting ? I remember it being auto align before ... -_-
struct datanode {
volatile int nodeval;
T val;
};
concurrency::concurrent_vector<datanode*> lst
inline T find(UINT32 key)
{
for (int i = 0; i < lst->size(); i++)
{
datanode* nd = lst->at(i);
//nd is invalid sometimes
if (nd)
if (nd->nodeval == key)
{
return (nd->val);
}
}
return NULL;
}
inline T insert_nonunique(UINT32 key, T val){
datanode* itm = new datanode();
itm->val = val;
itm->nodeval = key;
lst->push_back(itm);
_updated(lst);
return val;
}
The problem is using of concurrent_vector::size() which is not fully thread-safe as you can get reference to not yet constructed elements (where memory contains garbage). Microsoft PPL library (which provides it in concurrency:: namespace) uses Intel TBB implementation of concurrent_vector and TBB Reference says:
size_type size() const |
Returns: Number of elements in the vector. The result may include elements that are allocated but still under construction by concurrent calls to any of the growth methods.
Please see my blog for more explanation and possible solutions.
In TBB, the most reasonable solution is to use tbb::zero_allocator as underlying allocator of concurrent_vector in order to fill newly allocated memory with zeroes before size() will count it too.
concurrent_vector<datanode*, tbb::zero_allocator<datanode*> > lst;
Then, the condition if (nd) will filter out not-yet-ready elements.
volatile is no substitute for atomic<T>. Do not use volatile in some attempt to provide synchronization.
The whole idea of your find call doesn't make sense in a concurrent context. As soon as the function iterates over one value, it could be mutated by another thread to be the value you're looking for. Or it could be the value you want, but mutated to be some other value. Or as soon as it returns false, the value you're seeking is added. The return value of such a function would be totally meaningless. size() has all the same problems, which is a good part of why your implementation would never work.
Inspecting the state of concurrent data structures is a very bad idea, because the information becomes invalid the moment you have it. You should design operations that do not require knowing the state of the structure to execute correctly, or, block all mutations whilst you operate.

Should I be worried about having too many levels of vectors in vectors?

Should I be worried about having too many levels of vectors in vectors?
For example, I have a hierarchy of 5 levels and I have this kind of code
all over my project:
rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d]
where each element is a vector. The whole thing is a vector of vectors of vectors ...
Using this still should be lot faster than copying the object like this:
Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
// use b
The second approach is much nicer, but slower I guess.
Please give me any suggestion if I should worry about performance issues related to this,
or else...
Thanks
Efficiency won't really be affected in your code (the cost of a vector random access is basically nothing), what you should be concerned with is the abuse of the vector data structure.
There's little reason that you should be using a vector over a class for something as complex as this. Classes with properly defined interfaces won't make your code any more efficient, but it WILL make maintenance much easier in future.
Your current solution can also run into undefined behaviour. Take for example the code you posted:
Block b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
Now what happens if the vector indexes referred to by pos.a, pos.b, pos.c, pos.d don't exist in one of those vectors? You'll go into undefined behaviour and your application will probably segfault (if you're lucky).
To fix that, you'll need to compare the size of ALL vectors before trying to retrieve the Block object.
e.g.
Block b;
if ((pos.a < rawSheets.size()) &&
(pos.b < rawSheets[pos.a].countries.size()) &&
(pos.c < rawSheets[pos.a].countries[pos.b].cities.size()) &&
(pos.d < rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks.size()))
{
b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
}
Are you really going to do that every time you need a block?!!
You could do that, or you can, at the very least, wrap it up in a class...
Example:
class RawSheet
{
Block & FindBlock(const Pos &pos);
std::vector<Country> m_countries;
};
Block & RawSheet::FindBlock(const Pos &pos)
{
if ((pos.b < m_countries.size()) &&
(pos.c < m_countries[pos.b].cities.size()) &&
(pos.d < m_countries[pos.b].cities[pos.c].blocks.size()))
{
return m_countries[pos.b].cities[pos.c].blocks[pos.d];
}
else
{
throw <some exception type here>;
}
}
Then you could use it like this:
try
{
Block &b = rawSheets[pos.a].FindBlock(pos);
// Do stuff with b.
}
catch (const <some exception type here>& ex)
{
std::cout << "Unable to find block in sheet " << pos.a << std::endl;
}
At the very least, you can continue to use vectors inside the RawSheet class, but with it being inside a method, you can remove the vector abuse at a later date, without having to change any code elsewhere (see: Law Of Demeter)!
Use references instead. This doesn't copy an object but just makes an alias to make it more usable, so performance is not touched.
Block& b = rawSheets[pos.a].countries[pos.b].cities[pos.c].blocks[pos.d];
(watch the ampersand). When you use b you will be working with the original vector.
But as #delnan notes you should be worried more about your code structure - I'm sure you could rewrite it in a more appropriate and maintable way.
You should be worried about specific answers since we don't know what the constraints are for your program or even what it does?
The code you've given isn't that bad given what little we know.
The first and second approaches you've shown are functionally identical. Both by default will return an object reference but depending on assignment may result in a copy being made. The second certainly will.
Sasha is right in that you probably want a reference rather than a copy of the object. Depending on how you're using it you may want to make it const.
Since you're working with vectors, each call is fixed time and should be quite fast. If you're really concerned, time the call and consider how often the call is made per second.
You should also consider the size of your dataset and think about if another data structure (database perhaps) would be more appropriate.

assigning value from a vector (of shared pointer) to a shared pointer cause segmentation fault c++

In my code, I have a vector <vector <vector <vector <std::tr1::shared_ptr<foo> > > > > named foosBoxes. The nested vector has a role of simulating a physical boxes position. I also have a while loop which cause a segmentation fault:
vector<std::tr1::shared_ptr<foo> >::iterator fooit = foosBoxes[x][y][z].begin(); //x,y,z are valid integer
std::tr1::shared_ptr<foo> aFoo;
while (fooit != foosBoxes[x][y][z].end()){
aFoo = *fooit; //this cause segmentation fault
fooit++;
//some stuff which does not have an effect on fooit;
}
Some thing I have tried:
1. I have tried to use aFoo = *fooit++ but this didn't work.
2. The segmentation fault occurs roughly after several thousandths loops which went on fine.
3. I have tried to valgrind the problem and valgrind went through the step.
4. In the loop that crashes, I have printed a running counter before and after the suspected line. when before the line, I get 8 printings (the size of the vector) and when after I get 7 printings.
How can I figure this out?
Update:
I have added a loop to run before the main loop:
int kkk = 1214
int c = 0;
while (c < foosBoxes[x][y][z].end()){
aFoo = foosBoxes[x][y][z][c++];
printf("%i\t, kkk);
fflush(stdout);
}
Which yields the same results.
Update:
according to gdb:
Program received signal SIGSEGV, Segmentation fault.
0x000000000043e400 in rotate (kkk=1214) at
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/boost_shared_ptr.h:153
153 dispose();
I think that the appropriate function in boost_shared_ptr.h is
void
release() // nothrow
{
if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) == 1)
{
dispose(); //this is line 153
#ifdef __GTHREADS
_GLIBCXX_READ_MEM_BARRIER;
_GLIBCXX_WRITE_MEM_BARRIER;
#endif
if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1)
destroy();
}
}
dispose() is defined elsewhere in the file:
// dispose() is called when _M_use_count drops to zero, to release
// the resources managed by *this.
virtual void
dispose() = 0; // nothrow
Could it be that the reason is ill management of shared_ptr and I should switch back to regular pointer?
Update:
yet another test with similar result:
int kkk = 1214
int c = fooBoxes[x][y][z].size();
while (c >= 0){
aFoo = foosBoxes[x][y][z][c--];
printf("%i\t, kkk);
fflush(stdout);
}
This time the program crush in the third iteration. Should the problem was with wrong allocation, then the program should have crush in the first iteration (in the opposite direction the program crashes in the first iteration).
Run your code with libstdc++ in debug mode. It will do extra checks of iterators, containers and algorithms and hopefully will help to find the bug.
//some stuff which does not have an effect on fooit;
But does the stuff have any effect on foosBoxes[x][y][z]?
In particular does it remove elements or cause a vector relocation? If so, fooit cannot be compared meaningfully to foosBoxes[x][y][z].end().
Also, what happens to aFoo in the loop? If this gets an invalid value, an assignment to it later will cause undefined behaviour.
Try removing the some stuff from the loop. If that works the stuff contains a bug. If the loop still fails, the cause must be an invalid value in fooxBoxes[] before you enter the loop
I have no experience with ValGrind. But I have used similar products. Please check that you have configured ValGrind to its most strict settings. This might make using it painfully slow, but hopefully finds the bug.
You're code as it is looks okay, the only thing I can think is that are x y z valid? operator[] does no bounds checking...
I have came to the conclusion that the problem was with the use vector is wrong since I update it through the code. I don't know how the memory management in c++ works but I believe that some sort of overlapping between two vector occurred. I have switched to set and everything works now
To operate on an element of foosBoxes[x][y][z] you can also try:
while (fooit != foosBoxes[x][y][z].end()){
vector<std::tr1::shared_ptr<foo> > *aFoo = *fooit;
fooit++;
//To use the object
// use it as aFoo->method()
}
Not sure if i am making the point. But i am currently using pointers to iterate in my objects.

passing a vector between functions via pointers

It was suggested to me to use pointers to add a vector that I wanted to pass from some existing function to another function. I am really stuck on how to get the information back out of that pointer though. I've tried a number of things I've read here and there so let me demonstrate what I'm talking about.
primary program:
std::vector<float> * dvertex=NULL;
track.calculate(irrelevant stuff, dvertex)
secondary program (track, calculate)
track::caclulate(irrelevant stuff, vector<float> * dvertex)
{
...
vector<float> pos;
... pos filled after some calculations
if(! (dvertex==NULL))
{
dvertex = &pos1;
}
back to primary, unless I messed up something above, here's some things I've tried
1
(*dvertex).at(0)
float z = (*dvertex).at(0)
2
(*dvertex)[0]
and a bunch of stuff that just plain didn't compile. I'm quite stuck as I'm not sure how to get the specific values out of that vector in the main program. I even thought it might be the if(! (dvertex==NULL)) bit, so I changed it to if(dvertex==NULL) but still no joy. Any help would be greatly appreciated.
*Edit/Update*Thanks so much everyone for the help, but I fear I'm still doing it wrong.
So following the suggestions that I just pass a reference: I did this:
primary
std::vector<float> dvertex;
track.calculate( foo, &dvertex);
secondary stayed the same (with !Null check)
primary
std::cout<<dvertex[0]<<std:endl;
(among other attempts to actually use the data)
Thanks a lot for any thoughts on what I'm still doing improperly. Everything compiles, the program just freezes when it gets to a point that the data from dvertex is used.
Edit:Final fix
in the secondary program I needed
*dvertex = pos1;
instead of
dvertex = &pos1;
I'm not sure why these didn't compile for you, because they're valid as long as the pointer is valid and not null:
void f(std::vector<int>* v)
{
if( v != 0 ) {
int n = (*v)[0]; // ok
int m = (*v).at(0); // ok
int o = v->at(0); // ok
}
}
But never mind that. Use a reference if you must change the vector, and a const reference if you must not. There's rarely if ever a need to take a container by pointer.
Also, I suggest you check pointers against 0, not NULL, because sometimes NULL is defined as (void*)0 as per C compilers. But some people may argue otherwise here.
If you're going to modify the vector, you probably just want to pass it by reference. If you do use a pointer, however, you need to define a vector in main, and then pass the address of that vector:
void calculate(std::vector<float> *vertex_array) {
vertex_array->pushback(1.0f);
vertex_array->pushback(2.0f);
}
int main() {
std::vector<float> vertexes;
calculate(&vertexes);
std::copy(vertexes.begin(), vertexes.end(),
std::ostream_iterator<float>(std::cout, "\n"));
return 0;
}
See my note above, but for your scenario to work, you need
std::vector<float> * dvertex=NULL;
to be
std::vector<float> * dvertex = new std::vector<float>();