以下代码是将“非重叠”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)
答案 0 :(得分:1)
std::vector<T>::push_back
(通常)允许使与vector
对象关联的所有迭代器无效。所以在你这样做之后:
u.push_back(*it1);
使用++it2
继续内部for循环是不安全的。
您可以使用内部循环的索引。或者,如果您真的不想在push_back
中使用相同TablePath*
指针的多个副本,请在执行u
后立即跳出内循环。