我遇到了段错误,并通过简化main()函数并使用valgrind来缩小出现问题的范围。
main.cpp
int main() {
unique_ptr<Graph> g1 = make_unique<Graph>();
unique_ptr<Graph> g2 = make_unique<Graph>();
for (int i = 0; i < 10; i++) {
g1->insert(1,0+i,1+i);
cout << i << endl;
g2 = g1->copy();
}
}
使用valgrind时程序的输出:
0
1
==10545== Invalid read of size 8
==10545== at 0x110612: std::vector<unsigned int,std::allocator<unsigned int> >::push_back(unsigned int const&) (in /home/user/Program/C++/main)
==10545== by 0x1176F9: Graph::insert(unsigned int,unsigned int,unsigned int) (in /home/user/Program/C++/main)
==10545== by 0x117D5B: Graph::copy() (in /home/user/Program/C++/main)
==10545== by 0x10D5DA: main (in /home/user/Program/C++/main)
==10545== Address 0x10 is not stack'd,malloc'd or (recently) free'd
当我尝试在增加大小(默认矩阵为2x2)后尝试复制Graph对象时,似乎发生SEGFAULT。我不知道为什么会这样,我只知道在matrix[n1][n2]->v.push_back(value)
中到达insert()
时会发生这种情况
图形类(简体):
class Graph {
private:
struct Edge {
// fields...
vector<unsigned int> v;
// functions...
}
unsigned int size = 2;
vector<vector<shared_ptr<Edge>>> matrix = vector<vector<shared_ptr<Edge>>>(size,vector<shared_ptr<Edge>>(size));
void resize(unsigned int newSize) {
matrix.resize(newSize);
for (unsigned int i = 0; i < newSize; i++) {
matrix[i].resize(newSize);
}
if (newSize > size) {
for(unsigned int j = 0; j < newSize-1; j++) {
matrix[j][newSize-1] = make_shared<Edge>();
matrix[newSize-1][j] = matrix[j][newSize-1];
}
matrix[newSize-1][newSize-1] = matrix[0][0];
}
size = newSize;
}
public:
Graph() { // matrix[i][j] = matrix[j][i],matrix[i][i] = invalid
shared_ptr<Edge> E = make_shared<Edge>();
shared_ptr<Edge> other = make_shared<Edge>(); // placeholder,not to be used
matrix[0][0] = other;
matrix[0][1] = E;
matrix[1][0] = E;
matrix[1][1] = other;
}
~Graph() {
vector<vector<shared_ptr<Edge>>>().swap(matrix);
}
char insert(unsigned int value,unsigned int n1,unsigned int n2) {
if (n1==n2) return 0;
if (n1 > n2) {
int temp = n1;
n1 = n2;
n2 = temp;
}
if (value==0 || n2>size || (n2==size&&n1 < size-1)) return 0;
if (n2 == size) {
resize(size+1);
}
matrix[n1][n2]->v.push_back(value); // SEGFAULT HERE!!
return 1;
}
// segfault seems to happen when resizing ?
unique_ptr<Graph> copy() {
unique_ptr<Graph> thisCopy = make_unique<Circuit>();
if(size!=2) thisCopy->resize(size);
for (unsigned int i = 0; i < size-1; i++) {
for (unsigned int j = 0; j < size; j++) {
if (i!=j) {
for (unsigned int n: matrix[i][j]->v) {
thisCopy->insert(n,i,j); // <--error happens here
}
}
}
}
return thisCopy;
}
}
以某种方式调整矩阵大小时,Edge结构的v字段是否被错误地重新分配?我尝试查看this answer,但就我而言,v只是一个向量,所以我不知道为什么这对我适用。