Eyzuky Eyzuky - 3 months ago 19
C Question

Incompatible pointer type - C

I have this structure of structs, presented in this code:

typedef void* DataP;
typedef struct Table* TableP;
typedef const void* ConstKeyP;

typedef struct DataPointer
{
DataP dataP;
ConstKeyP key;
}DataPointer;

typedef struct HashTableSet
{
DataPointer *hashSet[MAX_ROW_ELEMENTS];
}HashTableSet;

typedef struct HashTableSet *HashTable;

typedef struct Table
{
int size, d;
HashTable hashTable;
}Table;


That is the structure.
Now here is the function that creates the hash table -

TableP createTable(size_t tableSize)
{
TableP tableP = (TableP)malloc(sizeof(Table));
HashTable table = (HashTable)malloc(sizeof(HashTable));
tableP->d = 1;
tableP->size = tableSize;
nullTable(tableP);
return tableP;
}


where nullTable is a function that i want to both to give memory for the actual sets and also give null initial value:

void nullTable(TableP tableP)
{
HashTable hashTable = tableP->hashTable;
int i = 0;
for(; i < tableP->size; i++)
{
int j = 0;
HashTableSet *hashTableSet = (HashTableSet*)malloc(sizeof(HashTableSet));
for (; j < MAX_ROW_ELEMENTS ; ++j)
{

DataPointer *data = (DataPointer*)malloc(sizeof(HashTableSet));
hashTableSet->hashSet[j] = data;
}
hashTable[i] = *hashTableSet;
//hashTable->hashSet = *hashTableSet;
hashTable += sizeof(HashTableSet);

}
}


First question comes up here - in the last lines of nullTable, i am trying to "jump" my pointer of hashTable to the next set memory. meaning i have allocated all the space i need for a set, pointed my hashTable[i] at it, and then i added sizeof(HashTableSet) to hashTable because i want it to get to the next "spot" for another hashTableSet. This already fills like i am doing something wrong.

Next i reach to my real problem of understanding how this pointer iterating works in this function:

DataP removeData(TableP table, const void* key)
{
TableP tableP = table;
int cell = table->hfun(key, table->size);
HashTable hashTable = table->hashTable;
HashTableSet *setPtr = hashTable->hashSet;
int i = 0;
int j = 0;
int d = 1;
while(d < tableP->d)
{
for (; i < MAX_ROW_ELEMENTS; i++)
{
if (table->fcomp(setPtr->hashSet[i]->key, key) == 0)
{
DataP dataP = setPtr->hashSet[i]->dataP;
setPtr->hashSet[i] = NULL;
table->freeKey((void*)key);
return dataP;
}
}
setPtr *= 2;
i = 0;
}
return NULL;
}


I want setPtr to point at the first HashTableSet of my table. But i get this error message:

warning: initialization from incompatible pointer type
HashTableSet *setPtr = hashTable->hashSet;


I am also having a problem understanding how to take setPtr to the next hashSet, assuming that i managed to actually define setPtr correctly for my needs.

Answer

From your definitions:

typedef void* DataP;
typedef struct Table* TableP;
typedef const void* ConstKeyP;

typedef struct DataPointer
{
    DataP dataP;
    ConstKeyP key;
}DataPointer;

typedef struct HashTableSet
{
DataPointer *hashSet[MAX_ROW_ELEMENTS];
}HashTableSet;

typedef struct HashTableSet *HashTable;

typedef struct Table
{
int size, d;
HashTable hashTable;
}Table;

From your code:

HashTable hashTable = tableP->hashTable;
HashTableSet *setPtr = hashTable->hashSet;

So hashTable of type HashTable which is struct HashTableSet*. So far so good. The next line is the problem: HashTableSet *setPtr = hashTable->hashSet;

hashTable->hashSet is NOT of type HashTableSet!

This will work:

DataP removeData(TableP table, const void* key) 
  { 
      TableP tableP = table; 
      int cell = table->hfun(key, table->size); 
      HashTable hashTable = table->hashTable; 
      /*  
       * See change in the following line: 
       * Before the change you were trying to assign type  
       * `HashSet` into type `HashTableSet*`, this will   
       */ 
      HashTableSet *setPtr = hashTable;                                                         
      int i = 0;         
      int j = 0;         
      int d = 1;         
      while(d < tableP->d)         
      {         
          for (; i < MAX_ROW_ELEMENTS; i++)     
          {     
              if (table->fcomp(setPtr->hashSet[i]->key, key) == 0) 
              { 
                  DataP dataP = setPtr->hashSet[i]->dataP;
                  setPtr->hashSet[i] = NULL;
                  table->freeKey((void*)key);
                  return dataP;
              } 
          }     
          setPtr *= 2;     
          i = 0;     
      }         
      return NULL;         
  }      
Comments