function argument a pointer array (C) - c

in my code I have a array of pointers, where the pointers point to my struct
struct Container *bucket[sizeOfHashMap];
I have a function that will return 1 of these array pointers (e.g it may return the pointer at array index 6). As an argument it wants a pointer to this pointer. The function can be seen here:
struct Container* getWhichBucket(char word[], struct Container **bucket[10]){
int value = 0;
int i = 0;
int size = strlen(word);
int hashIndex = 0;
for(i =0; i < size; i++){
value += (int)word[i];
}
//size of array is worked out by getting memory that array takes up / a slot
hashIndex = value % sizeOfHashMap;
return *bucket[hashIndex];
}
I call the function like this (where test is an array of characters)
addToBucket(test, getWhichBucket(test, &bucket));
the add to bucket looks like this:
void addToBucket(char word[], container **bucket){
container *temp = (struct Container*)malloc (sizeof(struct Container));
strcpy(temp->key, word);
temp->value = 9001;
temp->next = *bucket;
*bucket = temp;
return;
}
However the compiler issues warnings when I compile the code and when I run it I get a segmentation error. Does anyone know why? The warnings can be seen here:
cw.c: In function ‘main’:
cw.c:86:2: warning: passing argument 2 of ‘getWhichBucket’ from incompatible pointer type [enabled by default]
cw.c:37:19: note: expected ‘struct Container ***’ but argument is of type ‘struct Container * (*)[(long unsigned int)(sizeOfHashMap)]’
cw.c:86:2: warning: passing argument 2 of ‘addToBucket’ from incompatible pointer type [enabled by default]
cw.c:56:6: note: expected ‘struct container **’ but argument is of type ‘struct Container *’

addToBucket(test, getWhichBucket(test, &bucket));
is passing a
struct Container *(*)[10]
to getWhichBucket. That's the wrong type, as the compiler says.
You can fix the prototype and implementation
struct Container* getWhichBucket(char word[], struct Container *(*bucket)[10]){
int value = 0;
int i = 0;
int size = strlen(word);
int hashIndex = 0;
for(i =0; i < size; i++){
value += (int)word[i];
}
//size of array is worked out by getting memory that array takes up / a slot
hashIndex = value % sizeOfHashMap;
return (*bucket)[hashIndex];
}
or change the call, but there's no easy way to get a struct Container **bucket[10] from a struct Container *bucket[10], so then you'd probably still want to change the type and implementation of getWhichBucket.
Since you're not modifying the bucket argument there, there's no need to pass the address, you can simply pass the struct Container *bucket[10] directly,
struct Container* getWhichBucket(char word[], struct Container *bucket[]){
int value = 0;
int i = 0;
int size = strlen(word);
int hashIndex = 0;
for(i =0; i < size; i++){
value += (int)word[i];
}
//size of array is worked out by getting memory that array takes up / a slot
hashIndex = value % sizeOfHashMap;
return bucket[hashIndex];
}
and call
addToBucket(test, getWhichBucket(test, bucket));

You need to change your declaration of addToBucket from
void addToBucket(char word[], container *bucket)
{
container *temp = (struct Container)malloc (sizeof(struct Container));
strcpy(temp->key, word);
temp->value = 9001;
temp->next = *bucket;
*bucket = temp;
return;
}
to
void addToBucket(char word[], Container *bucket)
{
Container *temp = malloc (sizeof(struct Container));
strcpy(temp->key, word);
temp->value = 9001;
temp->next = *bucket;
*bucket = temp;
return;
}
Note the change in case for Container -- case matters in C... container is not the same thing as Container.
Also... note... you should not cast malloc in C.

Related

Transferring data from queue to array

I'm trying to put integer data from each node in a queue into an array called arr. The data for each node is inputted by the user, say there's 5 nodes, and has 1 2 3 4 5, where node 1 stores a value of 1 and node 5 stores a value of 5. My code is below:
typedef struct linkedList {
int val;
struct linkedList *next;
} list;
I've tried doing the following but I'm getting a few warnings when I compile the code, I only included the body of the function and not the header or prototype and such.
int i;
int *arr;
list *node = NULL;
for(i = 0; i < 5; i++) {
arr[i] = (int*)malloc(sizeof(int));
arr = node->id;
node = node->next;
}
The errors that I get are: warning: assignment to ‘int *’ from ‘int’ makes pointer from integer without a cast and warning: variable ‘arr’ set but not used
How do I actually get the data from the queue into an array so that the array is arr[0]=1 and arr[4]=5]? Thanks.
Assuming you already have your linked list allocated correctly and you know the number of nodes (since you didn't post the code for your linked list) then your copy to array function should look like this.
int* copylist(struct LinkedList* ls,int numberofnodes){
int* arr = malloc(sizeof(int)*numberofnodes);
for(int index = 0; index < numberofnodes; ++index){
arr[index] = ls->val;
ls = ls->next;
}
return arr;
}

error: incompatible types when assigning to type ‘struct card’ from type struct card *’

Keep on getting this error in one of my functions. Not Sure why.
error: incompatible types when assigning to type struct card from type struct card *
Struct card** shuffleDeck(Struct card deck[], int size)
{
int i, j;
struct card temp;
struct card** dealerDeck;
dealerDeck = malloc(size*sizeof(struct card*)*4);
for(i=0; i<size; i++)
{
dealerDeck[i] = (struct card**)malloc(size*sizeof(struct card));
j = rand()%size;
temp = dealerDeck[i]; //ERROR ON THIS LINE
dealerDeck[i] = dealerDeck[j];
dealerDeck[j] = temp; //ERROR ON THIS LINE
}
};
Any help appreciated!
Firstly, to make this temp = dealerDeck[i]; happen temp should be type struct card *temp
struct card *temp = NULL;
/* memory allocation */
temp = dealerDeck[i]; /* now its possible */
Also avoid casting malloc.

How to initialize an void* pointer from struct

I have a struct Element. When I try to initialize the elements array to NULL,
I get the error: incompatible types when assigning to type Element from type void *.
How to initialize the void * array?
typedef struct _Element Element;
struct _Element {
void* data;
};
typedef struct _ArrayList ArrayList;
struct _ArrayList {
int size;
Element *elements;
};
int main() {
ArrayList *list;
list->size = 100;
list->elements = (Element*)calloc(sizeof(Element), list->size);
for (i = 0; i < list->size; i++) {
/*
* error: incompatible types when assigning to type
* ‘Element’ from type ‘void *’
*/
list->elements[i] = NULL;
}
}
Firstly, you never allocated memory for your list object! Your list pointer is uninitialized and points nowhere. Trying to apply the -> operator to it causes undefined behavior.
I don't know what your final intent is, but it should be either something like
ArrayList *list = malloc(sizeof *list);
list->size = 100;
...
or
ArrayList list;
list.size = 100;
...
Secondly, your void * pointer is actually a named field called data inside Element struct
for(i = 0; i < list->size; i++)
list->elements[i].data = NULL;
Thirdly, becuse you used calloc the memory is already sort of "initialized" with all-zero bit-pattern (including your data fileds). Formally, such bit-pattern in void * is not guaranteed to represent a null pointer, but on most platforms it actually does.
P.S. Don't cast the result of calloc
list->elements = calloc(sizeof(Element), list->size);
or event better
list->elements = calloc(sizeof *list->elements, list->size);
Apart from all the logical errors, the compiler error is the result of trying to assign a value (NULL) to a struct-typed variable. The fact that the struct contains a void * is coincidental. You'd get the same error with:
typedef struct _Element Element;
struct _Element{
int data;
};
Element e;
e = NULL;
This is most likely a mistake from what you intended to do, which is assign a value to the variable inside the struct:
for(i = 0; i < list->size; i++)
list->elements[i].data = NULL;

Creating array of pointers

I need to create an array to pointers of pNodes but when i declare it i dont know the length of the array
lets see what i mean
this is the Node struct
typedef struct _Node {
struct _Node* next;
pElement element;
} Node, *pNode;
this is the Hash struct
typedef struct _Hash {
int hashSize;
pNode *hashTable;
}Hash,*pHash;
now i want each of the
hashTable boxes to point to a pNode
the problem is that i dont know the size of the array, if i did it would be like (i guess)
pNode hashTable[hashSize]
the way i wrote it and tried to resett all boxes to NULL:
this is the CODE:
allocation memory:
pHash hash = (pHash)(malloc(sizeof(Hash)));
hash->hashTable = (pNode)(malloc(sizeof(pNode) * size));
hash->hashSize = size;
resetHashTable(hash->hashTable, size); // reseting the array to NULLS
the func:
static void resetHashTable(pNode *hashTable, int size) {
int i;
for (i = 0; i < size; i++) {
hashTable[i] = (pNode)NULL;
}
}
one of the many many errors i get from the program is (the first error)
hash.c:37:18: warning: assignment from incompatible pointer type [enabled by default]
hash->hashTable = (pNode)(malloc(sizeof(pNode) * size));
can i have some pointers how i need to write it?
If this is not C++ just don't cast malloc, you have an error in this line
hash->hashTable = (pNode)(malloc(sizeof(pNode) * size));
It could be
hash->hashTable = (pNode *)(malloc(sizeof(pNode) * size));
// ^ hashTable is declared pNode *
A better solution would be
hash->hashTable = malloc(sizeof(pNode) * size);
You are declared the pNode as a pointer. Then in Hash structure You are declared the pNode * hastable So you have to use the double pointer **. Or else make that as single pointer in hash structure.
hash->hashTable = (pNode*)(malloc(sizeof(pNode) * size));

incompatible pointer type error C

So I'm trying to implement a cache in C. I have included a very slimmed down version of my code.
I keep getting this error:
prog.c: In function ‘addtolist’:
prog.c:29: warning: assignment from incompatible pointer type
prog.c:40: warning: assignment from incompatible pointer type
prog.c: In function ‘main’:
prog.c:72: warning: assignment from incompatible pointer type
from this code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct node_
{
char * word;
int filenumber;
struct node * next;
};
typedef struct node_ * node;
node createnode()
{
node head;
head = malloc(sizeof(struct node_));
head->word = NULL;
head->next = NULL;
return head;
}
unsigned int addtolist(node head, char * word, unsigned int limit, int fileno)
{
unsigned int templimit = limit;
node temp;
node temphead = head;
while(temphead->next != NULL)
{
temphead = temphead->next;
}
temp = malloc(sizeof(struct node_));
temp->word =(char*) malloc(strlen(word)+ 1);
strcpy(temp->word, word);
temp->next = NULL;
temp->filenumber = fileno;
templimit = templimit - (strlen(word) + 1) - sizeof(struct node_)- sizeof(int);
printf("templimit is size %u\n", templimit);
if (templimit < limit && templimit > 0)
{
temphead->next = temp;
limit = limit - strlen(word) - 1 - sizeof(struct node_)- sizeof(int);
return limit;
}
else
{
free(temp->word);
free(temp);
return 0;
}
}
int main()
{
node newlist = createnode();
int i = 0;
unsigned int limit = 65;
unsigned int temp = limit;
while(temp > 0 && temp <= limit)
{
temp = addtolist(newlist, "Hello", temp, i);
i++;
printf("new limit is - \t%u\nfilenumber is - \t%d\n", temp,i);
}
node ptr = newlist;
while(ptr->next != NULL)
{
printf("node %d contains the word %s\n", ptr->filenumber, ptr->word);
ptr = ptr->next;
}
return 1;
}
I honestly can't figure out what I'm doing wrong... My logic was that, since I was typedef'ing my struct as a pointer, after I created the struct in memory, I would be able to easily step through the ensuing list. Where was the flaw in my logic?
EDIT the initial problem was fixed (I forgot an underscore in my type declaration for struct node_ next;.
Now I'm having another problem: when I try to step through the list at the bottom of my code to print out the words contained in the list, I'm basically not able to step through the list. I keep outputting:
templimit is size 43
new limit is - 43
filenumber is - 1
templimit is size 21
new limit is - 21
filenumber is - 2
templimit is size 4294967295
new limit is - 0
filenumber is - 3
node 0 contains the word (null)
node 0 contains the word Hello
For some reason, it seems that my program isn't storing my changes to my list in memory after the first iteration. Any ideas on what I'm doing wrong?
Once again, any help would be appreciated, and thanks.
Inside your structure definition you have struct node without the underscore.
you'd better have a forward declaration
typedef struct node node;
and then declare your structure
struct node {
...
node *next;
};
no need to have this underscore stuff and hiding the * in a typedef. That only makes you mix things up easily.
String literals "like this" have type const char*, not char*, because they're immutable.
Fix your declarations to have const char* and the warnings will go away.
I think the struct member 'next' has to be declared as a (node_ *) type. As written it is currently (node_ **)

Resources