I've been getting a segfault and I narrowed down where the issue comes up by simplifying my main() function and using 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();
}
}
output from program when using 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
It looks like SEGFAULT occurs when I try to copy a Graph object after its size has increased (its default matrix is 2x2). I don't know WHY it's an issue, I just know it's happening when matrix[n1][n2]->v.push_back(value)
is reached in insert()
Graph class (simplified):
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;
}
}
Is the v field of my Edge struct getting improperly re-allocated when I resize the matrix in some fashion? I tried looking at this answer but in my case v is just an vector, so I don't know why that would apply for me.