开发者

Program crashes after call to push_back() for vector of pointers despite previous ok usage

I have a situation where i'm creating objects with new and storing a pointer to these objects in a vector. I later copy the pointer across to another vector and delete it from the original vector. In a seperate test program I have been able to do this with no trouble at all.

When added to a larger program I end up with a crash (the callstack at crash is added below). I've been unable to diagnose the problem so far, and have verified that all the pointers used lead to a valid memory location.

Where the vectors of are of the form

std::vector<Node*> openSet;
std::vector<Node*> closedSet;

Node is defined thusly

struct Node
{
    Node(sf::Vector2f &tilenode, Node *parentnode)
    {
        nodeposition = tilenode;
        parenttile = parentnode;
        gcost = 0;
    }

    sf::Vector2f nodeposition;
    Node *parenttile;
    float gcost;
};

The function's that cause the crash are:

void Pather::CreateNode(Node* node, string whichvec)
{
    if (whichvec == "openSet")
    {
        openSet.push_back(node);
    }
    else if (whichvec == "closedSet")
    {
        closedSet.push_back(node);
    }
}

void Pather::AddNode(sf::Vector2f thenode, Node *parentnode, string whichvec) 
{
    CreateNode(new Node(thenode, parentnode), whichvec);
}

Specifically the crash always happens at a call to openSet.push_back(node); This is called multiple times without problem in the program before the crash occurs.

The code used to copy is along the lines of

closedSet.push_back(openset[element]);
openSet.erase(openset.begin()+element-1);

The callstack at crash is

#0 0x7ffff680aba5   raise(sig=<value optimised out>) (../nptl/sysdeps/unix/sysv/linux/raise.c:64)
#1 0x7ffff680e6b0   abort() (abort.c:92)
#2 0x7ffff684443b   __libc_message(do_abort=<value optimised out>, fmt=<value optimised out>) (../sysdeps/unix/sysv/linux/libc_fatal.c:189)
#3 (    0x00007ffff684e4b6 in malloc_printerr(action=3, str=0x7ffff6922078 "double free or corruption (out) (malloc.c:6283)
#4 0x7ffff6854c83   __libc_free(mem=<value optimised out>) (malloc.c:3738)
#5 0x403d20 __gnu_cxx::new_all开发者_如何学Pythonocator<Pather::Node*>::deallocate(this=0x721dd0, __p=0x665c70) (/usr/include/c++/4.4/ext/new_allocator.h:95)
#6 0x403c30 std::_Vector_base<Pather::Node*, std::allocator<Pather::Node*> >::_M_deallocate(this=0x721dd0, __p=0x665c70, __n=16) (/usr/include/c++/4.4/bits/stl_vector.h:146)
#7 0x4080da std::vector<Pather::Node*, std::allocator<Pather::Node*> >::_M_insert_aux(this=0x721dd0, __position=..., __x=@0x7fffffffe490) (/usr/include/c++/4.4/bits/vector.tcc:361)
#8 0x407afc std::vector<Pather::Node*, std::allocator<Pather::Node*> >::push_back(this=0x721dd0, __x=@0x7fffffffe490) (/usr/include/c++/4.4/bits/stl_vector.h:741)
#9 0x407616 Pather::CreateNode(this=0x721dd0, node=0xc840c0, whichvec=...) (/home/nova/c++stuff/NewEng/pather.cpp:162)
#10 0x4076ae    Pather::AddNode(this=0x721dd0, thenode=..., parentnode=0xc84000, whichvec=...) (/home/nova/c++stuff/NewEng/pather.cpp:172)
#11 0x407389    Pather::FindPath(this=0x721dd0, stile=4840, ftile=4453) (/home/nova/c++stuff/NewEng/pather.cpp:102)
#12 0x40961b    Player::GetInput(this=0x721c90, window=...) (/home/nova/c++stuff/NewEng/player.cpp:42)
#13 0x403544    Engine::Events(this=0x7202d0) (/home/nova/c++stuff/NewEng/engine.cpp:46)
#14 0x4045fc    main() (/home/nova/c++stuff/NewEng/main.cpp:15)

I'm utterly stumped so far. So even a nudge in the right direction would be vastly helpful.


Shouldn't your node copy be:

closedSet.push_back(openset[element]);
openSet.erase(openset.begin()+element);

In your copy code think about what happens when element is 0. Basically you are not deleting the right node pointer from openSet when copying which will result in both leaked memory and double-freed pointers whenever you delete the nodes.


There's no problem with the code you've shown, but the code you've shown doesn't do what you describe (copy the pointer from one vector to another, then delete it in the first). If by delete it, you mean you call delete on the pointer, although it is still present in the second set, you're likely to run into troubles down the road, because you have a pointer to deleted memory. Otherwise, crashes in operator new are usually due to corruption of the free space arena. Earlier, and in totally unrelated code.

(Formally, anytime you have a pointer to deleted memory in a container, even temporarily, it's undefined behavior. Practically, as long as you don't dereference the pointer, it won't cause problems.)


From the callstack you can see

double free or corruption (out)

So it looks likely that something else is corrupting your memory. My first guess is that some code is double-deleting Nodes (does Node have a destructor you didn't show?).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜