New Beginning
New Beginning

Reputation: 13

segmentation fault 11, while pointer variables

I am trying to take input from console and add it to hash table. But I'm getting Segmentation fault 11. So, I debugged the program using gdb-apple. It is showing that I'm trying access memory I cannot, using the pointer variable. I think it is something obvious, but I'm missing it

This is what the gdb is displaying

     Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100000986 in CreateHashTable (size=200) at hashing.c:29
29                 h->Table[i]->next = NULL;

Here is the code

Header File:

#define LOAD_FACTOR 20
#define INITIAL_SIZE 200

struct HashTable *CreateHashTable(int size);
int HashSearch(struct HashTable *h,int data);
int HashInsert(struct HashTable *h,int data);
int HashDelete(struct HashTable *h, int data);
void Rehash(struct HashTable *h);
int Hash(int data, int size);


struct ListNode
{
        int key;
        int data;
        struct ListNode *next;
};

struct HashTableNode
{
        int bcount;
        struct ListNode *next;
};

struct HashTable
{
        int tsize;
        int count;
        struct HashTableNode **Table;
};

Implementation file:

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

struct HashTable *CreateHashTable(int size)
{
        struct HashTable *h;
        h = (struct HashTable *) malloc ( sizeof(struct HashTable) );
        if(h == NULL)
        {
                printf("Memory Error");
                return NULL;
        }
        h->tsize = (int) size/LOAD_FACTOR;
        printf("h->tsize = %d",h->tsize);
        h->count = 0;

        h->Table =  malloc ( ( sizeof(struct HashTableNode **) ) * (h->tsize) );

        if( h->Table == NULL )
        {
                printf("Memory Error");
                return NULL;
        }
        int i;

        for( i=0 ; i < (h->tsize) ; i++)
        {
               h->Table[i]->next = NULL;
               h->Table[i]->bcount = 0;
        }
        return h;
}

I would paste the rest of file, or Driver file, but I don't see it relevant. Please tell me why I'm getting the segmentation fault 11

Upvotes: 0

Views: 166

Answers (2)

David Ranieri
David Ranieri

Reputation: 41017

Your problem is here:

struct HashTableNode **Table;

You want an array of nodes (not a 2d array), change to:

struct HashTableNode *Table;

also change

 h->Table =  malloc ( ( sizeof(struct HashTableNode **) ) * (h->tsize) );

to

 h->Table = malloc(sizeof(struct HashTableNode) * h->tsize);

I think I want an array of pointers to nodes, don't I?

As pointed out by @WhozCraig, there is no reason for the additional level of indirection.

Example A (Pointer):

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

int main(void)
{
    int *a; /* pointer */
    int i, n = 10;

    a = malloc(n * sizeof(int)); /* space for 10 ints */
    for (i = 0; i < n; i++) {
        a[i] = i;
    }
    for (i = 0; i < n; i++) {
        printf("%d\n", a[i]);
    }
    free(a);
    return 0;
}

Example B (Pointer to pointer):

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

int main(void)
{
    int **a; /* pointer to pointer*/
    int i, n = 10;

    a = malloc(n * sizeof(int *)); /* space for 10 pointer to ints */
    for (i = 0; i < n; i++) {
        a[i] = malloc(sizeof(int)); /* space for 1 int */
        *a[i] = i;
    }
    for (i = 0; i < n; i++) {
        printf("%d\n", *a[i]);
        free(a[i]);
    }
    free(a);
    return 0;
}

As you can see both do the same thing, but the first one requires less memory and the code is cleaner.

One way to make it easy to remember is:

int * can hold an array

int ** can hold a table (NROWS * NCOLS)

int *** can hold an array of tables

Upvotes: 2

someuser
someuser

Reputation: 189

You allocated memory for array of pointers but you didn't allocate memory for members of this array.

    for( i=0 ; i < (h->tsize) ; i++)
    {
           h->Table[i] = malloc(...); //put correct arguments here and check allocation
           h->Table[i]->next = NULL;
           h->Table[i]->bcount = 0;
    }

Upvotes: 2

Related Questions