Glenville Pecor
Glenville Pecor

Reputation: 93

In C I am getting segmentation fault, i do not know why

I am making a Binary Search Tree that stores Multiple things in one instance, I have two errors That I ran into. The first one that happens in the function insert use to work in than randomly it stopped, the second one is in print_tree_inorder and I have no idea why that would be broken.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h> 
#include <string.h>
#include <malloc.h>


char* nameArray[50] = {};
char* number[50] = {};
char* ID[50] = {};
char* hours[50] = {};
char* pPH[50] = {};
int flag;
typedef struct node
{

    char* name;
    char* phoneNum;
    char* ID;
    char* hours;
    char* pPH;
    struct node * left;
    struct node * right;
} node_t;




void insert(node_t * tree, char* name, char* phoneNum, char* hours, char* pPH);
void print_tree_inorder(node_t * current);

int main()
{
    char* n,p,id,h,pph;
    int numberOfTimes = 0;

    node_t * test_list = malloc(sizeof(node_t));

    /* set values explicitly, alternative would be calloc() */
    test_list->name =  "";
    test_list->phoneNum = "";
    //test_list->ID = "";
    test_list->hours = "";
    test_list->pPH = "";


    test_list->left = NULL;
    test_list->right = NULL;
    printf("Please enter in the amount of people you want: ");
    scanf("%d",&numberOfTimes);
    printf("\n");

         for(int i = 0; i<numberOfTimes; i++){
             printf("Please enter in name: ");
             scanf("%s", &n);
             nameArray[i] = n; 

             printf("Please enter in PhoneNumber: ");
             scanf("%s", &p);
             number[i] = p;
             printf("Please enter in Hours: ");
             scanf("%s", &h);
             hours[i] = h;
             //printf("\n");
             printf("Please enter in pay per hour: ");
             scanf("%s", &pph);
             pPH[i] = pph;


            insert(test_list,nameArray[i],number[i],hours[i], pPH[i] );

        }

    printf("\n In order\n");
    print_tree_inorder(test_list);
}

void insert(node_t * tree, char* name, char* phoneNum,  char* hours, char* pPH)
{  
    //unsigned int number = (unsigned int)ptr

    if (tree->name == 0)
    {
        /* insert on current (empty) position */
        tree->name = name;
        tree->phoneNum = phoneNum;
        //tree->ID = ID;
        tree->hours = hours;
        tree->pPH = pPH;
    }
    else
    {

        if ( strcmp(tree->name, name) > 0)
        {
            /* insert left */
            if (tree->left != NULL)
            {
                insert(tree->left, name, phoneNum, hours, pPH);
            }
            else /* no left nodes*/
            {
                tree->left = malloc(sizeof(node_t));
                /* set values explicitly, alternative would be calloc() */
                tree->left->name = name;
                tree->left->phoneNum = phoneNum;

                tree->left->hours = hours;
                tree->left->pPH = pPH;
                tree->left->left = NULL;
                tree->left->right = NULL;
            }
        }
        else /*add node to right */
        {
            if ( strcmp(tree->name, name) <= 0)
            {
                /* insert right */
                if (tree->right != NULL)
                {
                    insert(tree->right, name, phoneNum,  hours, pPH);
                }
                else
                {
                    tree->right = malloc(sizeof(node_t));
                    /* set values explicitly, alternative would be calloc() */
                    tree->right->name = name;
                    tree->right->phoneNum = phoneNum;

                    tree->right->hours = hours;
                    tree->right->pPH = pPH;
                    tree->right->left = NULL;
                    tree->right->right = NULL;
                }
            }
        }
    }

}

void print_tree_inorder(node_t * current) {
    if (current == NULL) return;
    print_tree_inorder(current->left);
    printf(" %s %s %s %s\n", current->name, current->phoneNum,current->hours, current->pPH);

    print_tree_inorder(current->right);
}

Upvotes: 0

Views: 64

Answers (1)

H.S.
H.S.

Reputation: 12634

Several problems in your code. First of all you should not include malloc.h. It is deprecated.

Looks like there is some confusion around the declaration of n,p,id,h,pph variables. This statement:

char* n,p,id,h,pph;

declares only n as of type char * and rest of the variables p,id,h,pph declared as of type char.

Lets talk about the warnings reported by the compiler (I am using gcc compiler and providing -Wall and -Wextra options during compilation):

$ gcc -Wall -Wextra prg.c 
prg.c:56:26: warning: format specifies type 'char *' but the argument has type 'char **' [-Wformat]
             scanf("%s", &n);
                    ~~   ^~
prg.c:61:24: warning: incompatible integer to pointer conversion assigning to 'char *' from 'char'; take the address with & [-Wint-conversion]
             number[i] = p;
                       ^ ~
                         &
prg.c:64:23: warning: incompatible integer to pointer conversion assigning to 'char *' from 'char'; take the address with & [-Wint-conversion]
             hours[i] = h;
                      ^ ~
                        &
prg.c:68:21: warning: incompatible integer to pointer conversion assigning to 'char *' from 'char'; take the address with & [-Wint-conversion]
             pPH[i] = pph;
                    ^ ~~~
                      &
prg.c:35:15: warning: unused variable 'id' [-Wunused-variable]
    char* n,p,id,h,pph;
              ^
5 warnings generated.

You should not ignore the compiler warning messages. They are there for some reason.

Warning 1:
n is of type char * and therefore &n is of type char **. The %s format specifier in scanf() expects the argument as an array and the array must have room for at least input_size+1 characters.

You should declare n as array of characters, something like this:

char n[50];
// and for input
scanf("%49s", n);

Warning 2:

p is of type char and number[i] is of type char *. Hence the assignment is incompatible. Also the &p is of type char *, thats why the compiler is not reporting any warning on statement:

scanf("%s", &p);

But this is not correct because p is of type char and it does not have enough room for the string input. Read more about format specifiers of scanf().

You can do:

char p[50];
// and for input
scanf("%49s", p);
number[i] = strdup(p);

If you do not use strdup, all the pointers of number array end up pointing to same location. Alternatively, you can declare p as char * and explicitly handle the memory allocation/deallocation operation. Make sure to free the memory returned by strdup, once you are done with it. Same explanation for warning 3 and 4.

Warning 5:
Remove the unused variables from your code.

There is a scope of improvement in your code. Try to figure out them by yourself.

Upvotes: 1

Related Questions