push_back对象的指针导致段错误

时间:2013-11-30 02:48:52

标签: c++

以下代码是将“非重叠”TablePath从向量v移动到向量u。我在“u.push_back(* it1);”行遇到了段错误。我没有复制对象(而只是复制对象的指针)所以我认为问题不在于复制构造函数。你能给出一些关于为什么会发生段错误的提示吗?

#include <iostream>
#include <vector>
using namespace std;

class TablePath
{
    private:
        int source;
        int destination;
    public:
        TablePath(int,int);
        ~TablePath();
        int overlap(TablePath*);
        void toString();



        TablePath(const TablePath& that) : source(that.source), destination(that.destination)
    {
    }

};


TablePath::TablePath(int source=0,int destination=0)
{
    this->source = source;
    this->destination = destination;
}

int TablePath::overlap(TablePath* thatTablePath)
{
    if (this->source >= thatTablePath->source and this->source <= thatTablePath->destination)
        return 1;
    else if (this->destination >= thatTablePath->source and this->destination <= thatTablePath->destination)
        return 1;
    else if (thatTablePath->source >= this->source and thatTablePath->source <= this->destination)
        return 1;
    else if (thatTablePath->destination >= this->source and thatTablePath->destination <= this->destination)
        return 1;
    else
        return 0;
}

void TablePath::toString()
{
    cout << this->source << " " << this->destination << endl;
}

int main()
{
    int numofTests;
    cin >> numofTests;

    while(numofTests > 0)
    {
        int numofMoves;
        vector<TablePath *> v;
        cin >> numofMoves;

        for (int i=0;i<numofMoves;i++)
        {
            int source,destination;
            cin >> source >> destination;
            TablePath* MyTablePath = new TablePath(source,destination);
            v.push_back(MyTablePath);
        }

        vector<TablePath *> u;
        vector<TablePath *>::iterator it1 = v.begin();
        u.push_back(*it1);
        v.erase(v.begin()); 

        for(vector<TablePath *>::iterator it1 = v.begin(); it1 != v.end(); ++it1)
        {
            for(vector<TablePath *>::iterator it2 = u.begin(); it2 != u.end(); ++it2)
            {
                    if ((*it1)->overlap((*it2)))
                    {
                        u.push_back(*it1);
                    }
            }
        }

        cout << u.size() * 10;   
        v.erase(v.begin(),v.end());
        u.erase(u.begin(),u.end());
        numofTests--;
    }
}

以下是我从valgrind获得的输出:

frank@frank-vm:~$ valgrind --tool=memcheck ./tablepath
==6172== Memcheck, a memory error detector
==6172== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==6172== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==6172== Command: ./tablepath
==6172== 
1
3
10
20
15 30
20 50
==6172== Invalid read of size 4
==6172==    at 0x8048BB0: main (in /home/frank/tablepath)
==6172==  Address 0x4320184 is 0 bytes after a block of size 4 free'd
==6172==    at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==6172==    by 0x8049616: __gnu_cxx::new_allocator<TablePath*>::deallocate(TablePath**, unsigned int) (in /home/frank/tablepath)
==6172==    by 0x80493E8: std::_Vector_base<TablePath*, std::allocator<TablePath*> >::_M_deallocate(TablePath**, unsigned int) (in /home/frank/tablepath)
==6172==    by 0x8049230: std::vector<TablePath*, std::allocator<TablePath*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<TablePath**, std::vector<TablePath*, std::allocator<TablePath*> > >, TablePath* const&) (in /home/frank/tablepath)
==6172==    by 0x8048E00: std::vector<TablePath*, std::allocator<TablePath*> >::push_back(TablePath* const&) (in /home/frank/tablepath)
==6172==    by 0x8048BED: main (in /home/frank/tablepath)
==6172== 
==6172== Invalid read of size 4
==6172==    at 0x8048965: TablePath::overlap(TablePath*) (in /home/frank/tablepath)
==6172==    by 0x8048BCA: main (in /home/frank/tablepath)
==6172==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6172== 
==6172== 
==6172== Process terminating with default action of signal 11 (SIGSEGV)
==6172==  Access not within mapped region at address 0x0
==6172==    at 0x8048965: TablePath::overlap(TablePath*) (in /home/frank/tablepath)
==6172==    by 0x8048BCA: main (in /home/frank/tablepath)
==6172==  If you believe this happened as a result of a stack
==6172==  overflow in your program's main thread (unlikely but
==6172==  possible), you can try to increase the size of the
==6172==  main thread stack using the --main-stacksize= flag.
==6172==  The main thread stack size used in this run was 8388608.
==6172== 
==6172== HEAP SUMMARY:
==6172==     in use at exit: 48 bytes in 5 blocks
==6172==   total heap usage: 8 allocs, 3 frees, 64 bytes allocated
==6172== 
==6172== LEAK SUMMARY:
==6172==    definitely lost: 0 bytes in 0 blocks
==6172==    indirectly lost: 0 bytes in 0 blocks
==6172==      possibly lost: 0 bytes in 0 blocks
==6172==    still reachable: 48 bytes in 5 blocks
==6172==         suppressed: 0 bytes in 0 blocks
==6172== Rerun with --leak-check=full to see details of leaked memory
==6172== 
==6172== For counts of detected and suppressed errors, rerun with: -v
==6172== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

1 个答案:

答案 0 :(得分:1)

std::vector<T>::push_back(通常)允许使与vector对象关联的所有迭代器无效。所以在你这样做之后:

u.push_back(*it1);

使用++it2继续内部for循环是不安全的。

您可以使用内部循环的索引。或者,如果您真的不想在push_back中使用相同TablePath*指针的多个副本,请在执行u后立即跳出内循环。