Linked list question creating parent and child processes segmentation fault

Viewed 336

Hello im trying to figure out this bug in my code. Im creating/destroying basic linked lists. When I go to create a new child process to a specific index I get exit code 139 (signal 11: SIGSEGV). Specifically line 52 code

while (pcb_array[q].parent != -1) { q++; }

I looked at the cause of this problem being a segmentation fault.Im not too sure if my pointers are causing this or when I enter in a max number of process. Maybe somehow there is not enough processes for the new created child processes ? I appreciate any input and help. Thank you

Code

#include <stdio.h>
#include <stdlib.h>

/* Global variables */
int num_processes;

/* Link lists in C of children structures */
struct node1 {
    int process;
    struct node1 *link;
};

typedef struct node1 linked_list_type;

struct node2 {
    int parent;
    linked_list_type *children;
} *pcb_array = NULL;

typedef struct node2 pcb_type;

/* Print out hierarchy of processes Problem */
void PROCESSESPRINT() {
    linked_list_type *next;
    for(int i = 0; i < num_processes; i++) {
        if ((pcb_array[i].parent != -1) && (pcb_array[i].children != NULL)) {
            printf("PCB [%d] is the parent of: ",i);
            next = pcb_array[i].children;
            while (next != NULL) {
                printf("PCB[%d] ", next->process);
                next = next->link;
            }
        }
        printf("\n");
    }
}

void OPTION1 () {
    printf("Enter the maximum number of processes: ");
    scanf("%d", &num_processes);
    pcb_array = malloc(num_processes *sizeof(pcb_type)); /* allocate size of array dependant on variable num_processes */
    /* define first pcb */
    pcb_array[0].parent = 0;      /*  Note . operator is for accessing structure members */
    pcb_array[0].children=NULL;
    for (int i = 1; i < num_processes;) {
        pcb_array[i].parent = -1;
        return;
    }
}

void OPTION2(){
    int p;
    int q = 1;
    linked_list_type  *new_child, *next;
    printf("Enter the parent process index: ");
    scanf("%d", &p);
    while (pcb_array[q].parent != -1) { q++; }
    new_child = (linked_list_type*)malloc(sizeof(linked_list_type));
    new_child->process = q ;
    new_child->link = NULL ;
    pcb_array[q].parent = p;
    pcb_array[q].children = NULL;
    if (pcb_array[p].children == NULL) {
        pcb_array[p].children = new_child;
    }
    else {
        next = pcb_array[p].children;
        while (next->link != NULL) {
            next = next->link;
        }
    next->link = new_child;
    }
    PROCESSESPRINT();
}

void DESTROYCHILDREN(linked_list_type *node) {
    if (node == NULL) {
        return;
    }
    else {
        DESTROYCHILDREN(node->link);
        int q = node->process;
        DESTROYCHILDREN(pcb_array[q].children);
        free(node); /* This system call frees memory */
        pcb_array[q].parent = -1;
        node = NULL;
    }
}

/* OPTION 3 */
void OPTION3() {
    int p;
    printf("Enter the index of the process whose descendants are to be destroyed: ");
    scanf("%d", &p);
    OPTION2(pcb_array[p].children);
    pcb_array[p].children = NULL;
    return;
}

/* OPTION 4 */
void OPTION4() {
    if (pcb_array != NULL) {
        if (pcb_array[0].children != NULL) {
            DESTROYCHILDREN(pcb_array[0].children);
        }
        free(pcb_array);
    }
    printf("Quiting program...");
}

/* Main Function User Input */
int main() {
    int choice = 0;
    while(choice != 4) {
        printf("\nProcess creation and destruction \n ------------------------------ \n 1) Enter parameters \n 2) Create a new child process \n 3) Destroy all descendants of a process \n 4) Quit program and free memory \n");
        printf("\n ENTER SELECTION: ");
        scanf("%d", &choice);
        switch(choice) {
            case 1: printf ("\nPROCEDURE FOR OPTION #1 \n"),OPTION1(); break;
            case 2: printf ("\nPROCEDURE FOR OPTION #2 \n"),OPTION2(); break;
            case 3: printf ("\nPROCEDURE FOR OPTION #3 \n"),OPTION3(); break;
            case 4: printf ("\nPROCEDURE FOR OPTION #4 \n"),OPTION4(); break;
            default: printf("\nInvalid option!\n"); break;
        }
    }
}

Console example

Process creation and destruction 
 ------------------------------ 
 1) Enter parameters 
 2) Create a new child process 
 3) Destroy all descendants of a process 
 4) Quit program and free memory 

 ENTER SELECTION: 1

PROCEDURE FOR OPTION #1 
Enter the maximum number of processes: 5

Process creation and destruction 
 ------------------------------ 
 1) Enter parameters 
 2) Create a new child process 
 3) Destroy all descendants of a process 
 4) Quit program and free memory 

 ENTER SELECTION: 2

PROCEDURE FOR OPTION #2 
Enter the parent process index: 0
PCB [0] is the parent of: PCB[1] 

Process creation and destruction 
 ------------------------------ 
 1) Enter parameters 
 2) Create a new child process 
 3) Destroy all descendants of a process 
 4) Quit program and free memory 

 ENTER SELECTION: 2

PROCEDURE FOR OPTION #2 
Enter the parent process index: 0
Signal: SIGSEGV (Segmentation fault)

Screenshot of error

0 Answers
Related