1

I'm quite new to graphs and want to figure out my segmentation fault problem. My output is already correct but for some reason, as numShapes approach a higher number ~40, a segmentation fault error occurs.

Program Details: The circuit has two sides and you must determine if each shape can fit into side one, if it can't, determine if it can fit into side two, if it can't again, output none. No shape (with their specific X & Y Spacings) must be overlapping.

Thank you.

Code

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <iostream> 
#include <vector> 
using namespace std;


int numShapes, XSpacing,YSpacing;
vector<int> Dimension(2,0);

string delimiter(string temp);
void main_pr();
bool bounded(struct Graph* graph,vector<int> coordinates, int N);


struct Edge{ 
    int src, dest, part; 
    int Xll, Yll;                                
    int Xur, Yur;                               
}; 

struct Graph{ 
    int V, E; 
    struct Edge* edge; 
}; 

struct Graph* createGraph(int V, int E){ 
    struct Graph* graph =  
           (struct Graph*) malloc( sizeof(struct Graph) ); 
    graph->V = V; 
    graph->E = E; 
    graph->edge =  
        (struct Edge*) malloc( graph->E * sizeof( struct Edge ) ); 

    return graph; 
} 

int find(int parent[], int i){ 
    if (parent[i] == -1) 
        return i; 
    return find(parent, parent[i]); 
} 

// A utility function to do union of two subsets  
void Union(int parent[], int x, int y){ 
    int xset = find(parent, x); 
    int yset = find(parent, y); 
    if(xset!=yset){ 
       parent[xset] = yset; 
    } 
} 

struct Graph* graph;
struct Graph* graph2;



int main(){ 
int check = 0;
char _temp;
string temp;
string temp1,temp2;

for(int j=0;j<4;j++){
    while(_temp != '='){
        cin>>_temp;
    }
    _temp=0;
    cin>>temp;
    switch(j){
        case 0:
             numShapes = stoi(temp);
             if(numShapes == 0){
                 cout<<"Program terminating...\n";
                 return 0;
             }
        case 1:
             XSpacing = stoi(temp);
        case 2:
             YSpacing = stoi(temp);
        case 3:
            if(j==3)
            for(int i=0;i<temp.size();i++){
                if(temp[i] == 'x')
                    check = 1;
                if(check == 0)
                    temp1.push_back(temp[i]);
                else{
                    if(temp[i] != 'x')
                    temp2.push_back(temp[i]);
                }
        }
    }
}

 Dimension[0]=stoi(temp1);
 Dimension[1]=stoi(temp2);

   main_pr();

return 0; 
} 


void main_pr(){
string temp;    
vector<int> coordinates(4,0);
graph = createGraph(numShapes, numShapes); 
graph2 = createGraph(numShapes, numShapes); 
int a = 1;
int b = 1;
int check = 0;

for(int i=0; i<numShapes; i++){
        for(int j=0; j<4; j++){
            cin>>temp;
            switch(j){
                case 0:
                    coordinates[0] = stoi(delimiter(temp));
                    break;
                case 1:
                    coordinates[1] = stoi(delimiter(temp));
                    break;
                case 2:
                    coordinates[2] = stoi(delimiter(temp));
                    break;
                case 3:
                    coordinates[3] = stoi(temp);
                    break;
            }
        }
    if(i == 0){
    graph->V = 2; 
    graph->E = 2; 
    graph->edge[0].src = 0;
    graph->edge[0].dest = 1;
    graph->edge[0].Xll = coordinates[0];
    graph->edge[0].Yll = coordinates[1];
    graph->edge[0].Xur = coordinates[2];
    graph->edge[0].Yur = coordinates[3];
    cout<<"Side 1\n";
    }
    else if(bounded(graph,coordinates,a) == true){
        graph->V = a+2; 
        graph->E = a+2; 
        graph->edge[a].src = a;
        graph->edge[a].dest = a+1;
        graph->edge[a].Xll = coordinates[0];
        graph->edge[a].Yll = coordinates[1];
        graph->edge[a].Xur = coordinates[2];
        graph->edge[a].Yur = coordinates[3];
        a++;
        cout<<"Side 1\n";
    }
    else if(check == 0){
        graph2->V = 2; 
        graph2->E = 2; 
        graph2->edge[0].src = 0;
        graph2->edge[0].dest = 1;
        graph2->edge[0].Xll = coordinates[0];
        graph2->edge[0].Yll = coordinates[1];
        graph2->edge[0].Xur = coordinates[2];
        graph2->edge[0].Yur = coordinates[3];
        cout<<"Side 2\n";
        check = 1;
    }
    else if(bounded(graph2,coordinates,b) == true){
        graph->V = b+2; 
        graph->E = b+2; 
        graph2->edge[b].src = b;
        graph2->edge[b].dest = b+1;
        graph2->edge[b].Xll = coordinates[0];
        graph2->edge[b].Yll = coordinates[1];
        graph2->edge[b].Xur = coordinates[2];
        graph2->edge[b].Yur = coordinates[3];
        b++;
        cout<<"Side 2\n";
    }
    else{
        cout<<"None\n";
    }
}

}



bool bounded(struct Graph* graph,vector<int> coordinates, int N){ 
int *parent = (int*) malloc( graph->V * sizeof(int) ); 
int x = XSpacing - 1;
int y = YSpacing - 1;
int const Length = Dimension[0];
int const Height = Dimension[1];
int Xll = coordinates[0];
int Yll = coordinates[1];
int Xur = coordinates[2];
int Yur = coordinates[3];

memset(parent, -1, sizeof(int) * graph->V); 

    for(int i = 0; i < graph->E; ++i) 
    { 
        int A = find(parent, graph->edge[i].src); 
        int B = find(parent, graph->edge[i].dest); 

                if(Xll >= graph->edge[i].Xll-x && Xur <= graph->edge[i].Xur+x)              
                    if(Yll >= graph->edge[i].Yll-y && Yur <= graph->edge[i].Yur+y)
                        return false;

                if((Yll >= graph->edge[i].Yll-y && Yll <= graph->edge[i].Yur+y) || (Yur >= graph->edge[i].Yll-y && Yur <= graph->edge[i].Yur+y)){             //if on the right
                    if(Xll >= graph->edge[i].Xll-x && Xll <= graph->edge[i].Xur+x)
                        return false;
                    if(Xur <= graph->edge[i].Xur+x && Xur >= graph->edge[i].Xll-x)
                        return false;
                }

                if((Xll >= graph->edge[i].Xll-x && Xll <= graph->edge[i].Xur+x) || (Xur >= graph->edge[i].Xll-x && Xur <= graph->edge[i].Xur+x)){             //if on the right
                    if(Yll >= graph->edge[i].Yll-y && Yll <= graph->edge[i].Yur+y)
                        return false;
                    if(Yur <= graph->edge[i].Yur+y && Yur >= graph->edge[i].Yll-y)
                        return false;
                }

        if(A == B)
            return true;

        Union(parent, A, B); 
    } 
    cout<<endl;

return 0;
} 


string delimiter(string temp){

    if(temp.back() == ',')
        temp.pop_back();

return temp;
}

Input

NumShapes=8
XSpacing=10
YSpacing=2
Dimension=100x30
10, 4, 20, 6
25, 5, 55, 8 
10, 8, 15, 12
0, 20, 20, 22
0, 20, 10, 22 
0, 10, 5, 15 
25, 27, 75, 28
25, 10, 55, 13

Output

SIDE1
SIDE2
SIDE1
SIDE1
SIDE2
SIDE2
SIDE1
SIDE1
Bel
  • 45
  • 7
  • 1
    Why are you using `malloc` in a C++ program? – 1201ProgramAlarm May 27 '19 at 18:37
  • Hi! A Union Find block of code was provided already. :) – Bel May 27 '19 at 18:38
  • `struct Graph*) malloc` -- Run far away from the book, teacher, course, and/or institution that is teaching you this in a C++ course. Also, you are using `vector`, so why are you not using it everywhere where a vector could be used? Like here: `struct Edge* edge;` -- This could be simply `std::vector edge;` and then the `malloc` nonsense need not be done later on (just a `resize()` call). Of course you now would use `new` and remove the `malloc` calls everywhere, including where you create the graph object. – PaulMcKenzie May 27 '19 at 18:51
  • [See how much nicer the code looks](http://coliru.stacked-crooked.com/a/53b80bb5952efbfb). And another place where vector should be used `int *parent = (int*) malloc( graph->V * sizeof(int) );` -- could be `std::vector parent(graph->V);`. – PaulMcKenzie May 27 '19 at 19:04
  • The assignments to `graph->V` and `graph->E` under the `if(bounded(graph2,coordinates,b) == true)` condition of `main_pr` looks suspicious. – 1201ProgramAlarm May 27 '19 at 19:16
  • Oh I'm so sorry. It's my classmate who advised me to use the block of code. Thank you so much for your help. I'll try that now :) Thank you. – Bel May 27 '19 at 19:26

2 Answers2

1

Dont use malloc in c++ to create objects. Actually malloc does not create objects. Here

struct Graph* graph =  (struct Graph*) malloc( sizeof(struct Graph) );

you merely allocate memory for a Graph but you do not construct a Graph object.

From cppreference on std::malloc:

This function does not call constructors or initialize memory in any way. There are no ready-to-use smart pointers that could guarantee that the matching deallocation function is called. The preferred method of memory allocation in C++ is using RAII-ready functions std::make_unique, std::make_shared, container constructors, etc, and, in low-level library code, new-expression.

Ergo, use standard containers if you can, else use smart pointers. new is for low-level library code and malloc has no place in creating objects in C++.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
0

Replaced all malloc bits of codes to new. Segmentation Fault problem is now gone.

Bel
  • 45
  • 7