21

i'm breaking my head for hours on the following problem: i pasted 2 functions althought there are many more. i run valgrind on my program and i get 32 errors similar to this:

==4214== 6 errors in context 8 of 10:
==4214== Conditional jump or move depends on uninitialised value(s)
==4214==    at 0x40088F: getNextFreeCell (in /a/fr-01/vol/home/stud/ashers03/c/ex4/test)
==4214==    by 0x400C7A: InsertObject (in /a/fr-01/vol/home/stud/ashers03/c/ex4/test)
==4214==    by 0x401137: main (in /a/fr-01/vol/home/stud/ashers03/c/ex4/test)  

i get more errors on other functions, however it's same error. i can't understand why it is uninitialized.

This is the main function:

int main(int argc, char* argv[]) {
     size_t tableSize = (size_t)atoi(*(argv+1));
     TableP table = CreateTable(tableSize,IntFcn, IntPrint,IntCompare);
     int i;
     for (i=FIRST; i<=LAST; i++) {
         int *key = (int*)malloc(sizeof(int));
         *key = i;

         ObjectP obj = CreateObject(key);
         InsertObject(table,obj);
     }
     PrintTable(table);
     FreeTable(table);
     return 0;
}

these definitions are in a header file:

typedef struct Object* ObjectP;
typedef struct Table* TableP;
typedef const struct Table* ConstTableP;
typedef enum {FALSE, TRUE} Boolean;

this code is in another file:

typedef struct Table {
    ObjectP* _table;
    int _firstTableSize;
    int _currentTableSize;
    int _increaseFactor;
    HashFcn _hfun;
    PrintFcn _pfun;
    ComparisonFcn _fcomp;
} Table;

typedef struct Object {

     ObjectP _next;
     void* _key;
     int _numInChain;
} Object;

this function inserts a key to a hashtable. If 3 keys are already chained in the cell then size of the table is doubled and I'm doing some other things in doubleTable()...

Boolean InsertObject(TableP table, ObjectP object) {

    int index=table->_increaseFactor*table->_hfun(object->_key,table->_firstTableSize);

    if (table->_table[index] != NULL) {
        if (table->_table[index]->_numInChain == MAX_CHAIN) { //search for next cell
            int nextFreeCell = getNextFreeCell(table,index+1);
            if (nextFreeCell == FAILED) { //double table size
                if(doubleTable(table)) {
                InsertObject(table,object);
                return TRUE;
            }
            else {
                ReportError(MEM_OUT);
                return FALSE;
            }
        }
        else {
            table->_table[nextFreeCell] = chainObject(table->_table[nextFreeCell],object);
            return TRUE;
        }
    }
    else { //place object in chain:
        table->_table[index] = chainObject(table->_table[index],object);
        return TRUE;
    }
}
else { //empty cell, place object
     table->_table[index] = chainObject(table->_table[index],object);
     return TRUE;
}
}

static int getNextFreeCell(TableP table, int index) {

    int tableSize = table->_currentTableSize;
    while ( (index < tableSize) && (index % table->_increaseFactor != 0) ) {
         if (table->_table[index] == NULL || table->_table[index]->_numInChain < MAX_CHAIN) {
         return index;
         }
    index++;
    }
    return FAILED;
}

EDIT:

I ran valgrind as you said and I got:

==4563== Conditional jump or move depends on uninitialised value(s)
==4563==    at 0x40088F: getNextFreeCell (GenericHashTable.c:75)
==4563==    by 0x400C7A: InsertObject (GenericHashTable.c:222)
==4563==    by 0x401137: main (HashIntMain.c:34)
==4563==  Uninitialised value was created by a heap allocation
==4563==    at 0x4C241A7: malloc (vg_replace_malloc.c:195)
==4563==    by 0x4007AF: allocateArray (GenericHashTable.c:41)
==4563==    by 0x400924: doubleTable (GenericHashTable.c:90)
==4563==    by 0x400C8F: InsertObject (GenericHashTable.c:225)
==4563==    by 0x401137: main (HashIntMain.c:34)

I have this method:

static ObjectP* allocateArray(int tableSize) {

    objectP* arr = (ObjectP*)malloc(tableSize * sizeof(ObjectP));
        return arr;
}

this creates an array of pointers, which I never initialized. Could this be the problem? And how I should initialize a pointers array? To NULL?

Kyrol
  • 3,475
  • 7
  • 34
  • 46
Mike
  • 413
  • 1
  • 3
  • 13
  • 1
    Have you compiled your code with "-g" debug information? If so does it tell you the exact line or variable it is moaning about? – bramp Sep 01 '10 at 20:10
  • The alignment of `{}` in `InsertObject` function is misleading. The `{` after `if(doubleTable(table)) {` has no "aligned" pair. I don't know whether this was the intent, but it is difficult to see anything in such terribly misaligned code. – AnT stands with Russia Sep 01 '10 at 20:14
  • 2
    Just always use `calloc` for such cases. This is even the same number of characters to type: `objectP* arr = calloc(tableSize, sizeof(ObjectP));` and don't cast the return of `malloc` or `calloc` in C. This might hide you the lack of including the correct header files. – Jens Gustedt Sep 01 '10 at 21:13
  • possible duplicate of [pinpointing "conditional jump or move depends on uninitialized value(s)" valgrind message](http://stackoverflow.com/questions/2612447/pinpointing-conditional-jump-or-move-depends-on-uninitialized-values-valgrin) – Victor Sergienko Feb 20 '15 at 15:45

5 Answers5

44

You need to run valgrind with the --track-origins=yes option to find the origins of undefined values.

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
arsenm
  • 2,903
  • 1
  • 23
  • 23
10

The problem was that I didn't initialise the pointers array when I created it.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Mike
  • 413
  • 1
  • 3
  • 13
2

It looks to me that you didn't compile your program with a debugging flag (-g for gcc). Then if you run valgrind with all options on it should tell you exactly which variables cause the problem.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • i ran gcc -g *.c -o test and then valgrind -v test 7... same results, it's doesn't say in which variables.. – Mike Sep 01 '10 at 20:12
2

Where do you initialize table->_table? Check that you are properly initializing it in, I presume, CreateTable(). Please post the code for that function if nothing obvious pops out at you.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
2

Simple - just run

valgrind --tool=memcheck --track-origins=yes <program_path>

...to find out.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Subham Debnath
  • 689
  • 8
  • 9