0

I my code i call the insert function and it passes a pointer to the struct (table) and the insert function recieves a pointer and does some stuff and returns it again. But running the code gives segmentation fault. when i try to access the values in the struct array using the pointer passed.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define __USE_BSD
#include <string.h>

#include "speller.h"
#include "dict.h"

typedef struct 
{ // hash-table entry
  Key_Type element; // only data is the key itself
  enum {empty, in_use, deleted} state;
} cell;

typedef unsigned int Table_size; // type for size-of or index-into hash table

struct table 
{
  cell *cells; Table_size table_size; // cell cells [table_size];
  Table_size num_entries; // number of cells in_use
  // add anything else that you need
};

int hashfunc(Key_Type k, Table_size size)
{
    printf("enterd\n");
    char * d = k;
    int hash = 0;
    int c;
    printf("%s\n", d);
    printf("wtf??\n");
    while (c = *d++)
    {
        printf("maybehere??\n");
        hash = hash + c;
    }
    hash = hash%size;
    printf("%d\n", hash);
    return hash;
}

Table initialize_table (Table_size size) 
{
    Table t = malloc(sizeof(struct table));
    t->table_size = size;
    cell hash_table[size];
    for (int i=0; i<size; i++)
    {
        hash_table[i].state = empty;
        hash_table[i].element = "-";
        //printf("initialised\n");
    }
    t->num_entries = 0;
    t->cells = hash_table;
    /*for (int i = 0; i < t->table_size; i++)
    {
        printf("%d %s\n", i, (t->cells + i)->element);
    }*/
    return t;
}

int a = 0;
Table insert (Key_Type k, Table t) 
{
    //printf("insert called %d\n", a);
    printf("%d\n", t->table_size);
    //printf("%s\n", (t->cells + 2)->element);
    // as soon as program reaches here i get output like - 1 (NULL) 
    2 (NULL) and then segmentation fault
    for (int i = 0; i < t->table_size; i++)
    {
        printf("%d %s\n", i, (t->cells + i)->element);
    }
    a++;
    printf("%s\n", k);
    int hash_code = hashfunc(k, t->table_size);
    // Linear Probing
    printf("im here\n");
    while(strcmp((t->cells + hash_code)->element,"-") != 0)
    {
        if (strcmp((t->cells + hash_code)->element,k) == 0)
        {
            printf("return at if\n");
            return t;
        }
        else if (hash_code == (t->table_size - 1))
            hash_code = 0;
        else
            hash_code++;
    }
    (t->cells + hash_code)->element = k;
    (t->cells + hash_code)->state = in_use;
    t->num_entries += 1;
    printf("return at end with value %s\n", k);
    printf("inserted value %s\n", (t->cells + hash_code)->element);
    return t;

}

Boolean find (Key_Type k, Table t) 
{
    return FALSE;
}

void print_table (Table t) 
{
    Table_size size = t->table_size;
    for (int i = 0; i<size; i++)
    {
        if (strcmp((t->cells + i)->element,"-") != 0)
            printf("%d %s\n", i, (t->cells + i)->element);
    }
}

void print_stats (Table t) 
{
}

void main()
{

    Table table;
    Table_size table_size = 19;
    int a = 5;
    Key_Type input[5] = {"a","b","ab","abc","abcd"};
    table= initialize_table (table_size);
    //printf("%s\n", input[1]);
    while (a)
    {
        table= insert("a",table);
        a--;
    }
    printf("printing table\n");
    print_table(table);
}

this is the dict.h code

typedef char* Key_Type;
typedef struct table* Table;    // allows different definitions of struct table

Table initialize_table ();      // allows different parameters
Table insert (Key_Type, Table);
Boolean find (Key_Type, Table);
void print_table (Table);
void print_stats (Table);

This is the speller.h code

typedef enum {FALSE, TRUE} Boolean;

extern int verbose; // used to control monitoring output
extern int mode;    // used to control your algorithm

extern char *prog_name; // used by check

void check (void *memory) ; // check result from strdup, malloc etc.

I believe i dont understand how the pointers work in this program.

3
  • 3
    Don't typedef pointers, that's bad practice. You got me lost for a while, I didn't fined the typedef but I noticed you used the -> operator to access members. Also, consider checking if malloc() returned non-NULL pointer. Commented Mar 1, 2018 at 22:04
  • Isn't your compiler throwing warnings when compiling this code? Commented Mar 1, 2018 at 22:05
  • i dnt get any warnings no Commented Mar 1, 2018 at 22:35

1 Answer 1

1

Here is the problem,

cell hash_table[size];

and then, you make t->cells point to hash_table but hash_table is a local variable in the initialize_table() function, so it's destroyed/deallocated when the function returns and no longer accessible after it returns.

You should allocate it on the heap too, like this

cell *hash_table;
hash_table = malloc(size * sizeof(*hash_table));
if (hash_table == NULL)
    return NULL; // Probably free `t' so that no memory leaks
                 // happen

Accessing such a local variable that was allocated in the stack frame of a function, after that function returns is undefined behavior, the problem could happen somewhere else in the code or when accessing the pointer pointing to the deallocated data.

A side note

Be consistent with naming, and unambigous, you used a weird CamelCase and underscore combination, it doesn't matter if it's weird or not, keep it and preserve it throughout the code — respect your own style. And call the cell typedef: Cell instead.

Also, always check the return value of malloc() which returns NULL on error (allocation failure), you should write code as if all the bad things will happen, because they do.

And finally, never typedef a pointer. It doesn't help whatsoever, it only obscures the fact that a declaration is that of a pointer.

Sign up to request clarification or add additional context in comments.

2 Comments

also how do i free t if i am actually returning it??
Later you call a function free_table(t); that does all the freeing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.