-2

In order to understand tries I am creating this very simple C program that takes from user 10 nums from 0 to 9 as children of the trie. The final step is to print this nums with the function print, but I am getting a segmentation fault:

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

typedef struct list
{
    int data;
    struct list *ar[10];
} list;

void insert(list *head);
void print(list *head);

int main(void)
{
    printf("hello\n");
    list *root = malloc(sizeof(list));

    insert(root);
    print(root);    
}

void insert(list *head)
{
    int a, i;

    if (head == NULL) {
        return;
    }

    for (i = 0; i < 10; i++) {
        printf("Give Num 0-9\n");
        scanf("%i", &a);
        head->ar[a] = malloc(sizeof(head));
        head = head->ar[a];
        head->data = a;
    }
}

void print(list *head)
{
    if (head == NULL) {
        return;
    }

    while (head != NULL) {
        for (int i = 1; i < 10; i++) {
            if (head->ar[i] != NULL) {
                printf("%i", i);
                head = head->ar[i];
                break;
            }
        }
    }
    printf("\n");
}
Sean Bright
  • 118,630
  • 17
  • 138
  • 146
Spyreto
  • 29
  • 5
  • You never actually check the return value from `scanf` or whether `a` remains between 0-9 – Mark Nunberg Mar 31 '16 at 19:13
  • The object allocated by `malloc()` is uninitialized. You only write a valid value for `root->arr[a]`, but try to read (and dereference if they are non-null) all of the pointers in the array. – EOF Mar 31 '16 at 19:14
  • I make it in this way for simplicity, i am getting segme fault for correct values – Spyreto Mar 31 '16 at 19:16
  • 3
    Additionally, you are only allocating the size of the _pointer_, not the actual list structure! - perhaps you meant `malloc(sizeof(list))` instead? – Mark Nunberg Mar 31 '16 at 19:17
  • @Spyreto: In that case, you will need to provide a better example. The one you have provided obviously exhibits undefined behavior by using uninitialized values. – EOF Mar 31 '16 at 19:17
  • @Mark Nunberg you're right! thanks everyone for your time! – Spyreto Mar 31 '16 at 19:23

1 Answers1

0

There are several issues with your code:

  1. The first mention of malloc doesn't actually initialize the memory (the ar field). You should initialize it properly

    list *root = malloc(sizeof(list));
    

    Is missing initialization, e.g.

    root->data = 0;
    for (size_t ii = 0; ii < 10; ii++) {
        root->ar[ii] = NULL;
    }
    
  2. When you are actually gathering input, you allocate only enough memory for the pointer, not for the actual list itself.

    head->ar[a] = malloc(sizeof(head));
    

    should be initialized as above (head = malloc(sizeof(list)); for (size_t ...

  3. There seems to be an infinite loop when actually running your program (after correcting all these issues).

EDIT: Remove calloc...

Mark Nunberg
  • 3,551
  • 15
  • 18
  • `calloc()` is unsuitable for pointers, since there is no requirement for `NULL` to be bitwise-zero. Don't advocate unportable code. – EOF Mar 31 '16 at 19:29
  • [`%i` is fine](https://en.wikipedia.org/wiki/Scanf_format_string#Format_string_specifications), arguably better than `%d`, but probably overkill in this particular case. It does what `%d` does plus deal with base 16 and base 8 input. – Schwern Mar 31 '16 at 19:32
  • 1
    wow, I could have gone through years of never having heard of `%i`. oh well – Mark Nunberg Mar 31 '16 at 19:35