C – Segmentation Fault with strcmp?

Apart from the possibility that the values in your htable may be invalid pointers (i.e., neither NULL nor a pointer to a decent C string), you have a serious problem of encountering an infinite loop if it contains neither a NULL nor the string you’re looking for.

For the immediate problem, try changing the code to:

#define FLUSH fflush (stdout); fsync (fileno (stdout))

int linear_probe (htable h, char *item, int k) {
    int pos = k;
    do {
        pos = (pos + 1) % h->capacity;
        printf ("========\n");                    FLUSH;
        printf ("inpk: %d\n",   k);               FLUSH;
        printf ("posn: %d\n",   pos);             FLUSH;
        printf ("cpct: %d\n",   h->capacity);     FLUSH;
        printf ("keyp: %p\n",   h->keys[pos]);    FLUSH;
        printf ("keys: '%s'\n", h->keys[pos]);    FLUSH;
        printf ("item: '%s'\n", item);            FLUSH;
        printf ("========\n");                    FLUSH;
    } while ((pos != k)
          && (h->keys[pos] != NULL)
          && (strcmp (h->keys[pos], item) != 0));
    return pos;

Those debug statements should give you an indication as to what’s going wrong.

Since you’re getting:

inpk: -2055051140
posn: -30
cpct: 113
keyp: 0x100000001

right before the crash, it’s evident that someone is passing in a bogus value for k. The modulo operation on negative numbers is implementation defined in the C standard so you’re getting a negative value for pos as well. And since h->pos[-30] is going to be undefined behaviour, all bets are off.

Either find and fix the code that’s passing in that bogus value (probably an uninitialised variable) or protect your function by changing:

int pos = k;


int pos;
if ((k < 0) || (k >= h->capacity))
    k = 0;
pos = k;

at the start of your function. I’d actually do both but then I’m pretty paranoid 🙂

And, based on yet another update (the hash key calculation, if you generate an unsigned int and then blindly use that as a signed int, you’ve got a good chance of getting negative values:

#include <stdio.h>

int main (void) {
    unsigned int x = 0xffff0000U;
    int y = x;
    printf ("%u %d\n", x, y);

This outputs:

4294901760 -65536

My suggestion is to use unsigned integers for values that are clearly meant to be unsigned.

Leave a Comment