Dynamic data structure for Union Struct in C - c

Given this struct
struct node {
struct node* next;
union {
int lockId;
pthread_t threadId;
} id;
};
What is the correct way to initialize a dynamic array using malloc/realloc to store pointers to this struct?
I have tried:
struct node* nodes = (struct node*)malloc(n * sizeof(struct node*));
but I when compiling I get an error saying: initializer element is not constant
even though I am using #define MAXNODES 10
As for now, I am currently using a static array (fixed-size) by doing:
node *(nodes[MAXNODES]);
Any help would be greatly appreciated!

There is no problem with your data struct here, using an Union or not doesn't matter.
Your problem comes from the fact that the syntax for creating arrays is not correct.
In the following you can see how to create both dynamic and static arrays:
#include <stdlib.h>
#include <pthread.h>
#define MAX_NODES 10
struct node {
struct node *next;
union {
int lockId;
pthread_t threadId;
} id;
};
int main()
{
struct node nodes_static[MAX_NODES];
int n = MAX_NODES;
struct node* nodes_dynamic = (struct node*)malloc(sizeof(struct node) * n);
}
Please also note, that it is good practice to verify the return value of a dynamic allocation and that the dynamic memory should be freed after use.

Related

C - Trying to make an array of LinkedList pointers

I'm trying to create a HashTable in C where each 'bucket' is a pointer to a LinkedList. That is, I need to create an array of LinkedList pointers.
As of now, SomeHashTable->Buckets[i] is returning a non-pointer LinkedList. I've been looking for answers everywhere and I just can't find anything. Perhaps I'm overlooking something? I've given my current code below.
HashTable.h
#include "LinkedList.h"
typedef struct HashTable
{
LinkedList* Buckets[1009];
} HashTable;
//Creates new hashtable
HashTable* HashTable_new();
//Hashes and adds a new entry
void HashTable_add(HashTable* Table, int data);
HashTable.c
#include "HashTable.h"
HashTable* HashTable_new()
{
HashTable* newTable = (HashTable*)malloc(sizeof(HashTable));
newTable->Buckets = malloc(1009 * sizeof(LinkedList*));
//Create linked lists
for (int i = 0; i < 1009; i++)
{
newTable->Buckets[i] = LinkedList_new();
}
return newTable;
}
void HashTable_add(HashTable* Table, int data)
{
int index = data % 1009;
//Get bucket to hash to
LinkedList* BucketHead = (Table->Buckets[index]);
//Hash it iiinnnn real good
LinkedList_add_at_end(BucketHead, data);
}
The linked List structs for reference:
typedef struct LinkedListNode {
int data;
struct LinkedListNode *next;
struct LinkedListNode *prev;
} LinkedListNode;
typedef struct LinkedList {
struct LinkedListNode *first;
struct LinkedListNode *last;
} LinkedList;
As H.S.'s comment mentions, there is no need to dynamically --and-- statically allocate the Buckets array.
This line:
newTable->Buckets = malloc(1009 * sizeof(LinkedList*));
is overwriting the pointer to the statically allocated array, which is probably not what you want. For scalability, I would ditch the static array and stick with malloc(). That way you could use an argument to HashTable_new() to specify the size of the buckets array, like so:
HashTable* HashTable_new(int nBuckets)
{
HashTable* newTable = (HashTable*)malloc(sizeof(HashTable));
newTable->Buckets = malloc(nBuckets * sizeof(LinkedList*));
newTable->nBuckets = nBuckets;
//Create linked lists
for (int i = 0; i < nBuckets; i++)
{
newTable->Buckets[i] = LinkedList_new();
}
return newTable;
}
Notice that newTable->Buckets is being allocated as a pointer to a pointer to LinkedList (LinkedList**). You'll need to keep track to the size of Buckets[], so add the variable to the struct as follows:
typedef struct HashTable
{
int nBuckets;
LinkedList **Buckets;
} HashTable;
You should be good as long as LinkedList_new()'s return type is LinkedList*, and don't forget to free() it all when you're done.

Modifying a structure passed as pointer in C

I'm a noob student trying to write a program that uses binary search tree to organize the workers of a company. My teacher told me if I want to be able to create a new instance of the Worker structure, i can use malloc with the structure, which will return pointer to a new struct every time it's used, then i can edit the details of that new struct from another function. But how can i do it? No matter what i do it gets so complicated and i can't do it. Here's the code i've been able to write this part of the code, just to test if i can create and edit a new structure.
The main thing i ask is, how can i edit the newly created structure?
#include<stdlib.h>
#include<stdio.h>
struct btnode
{
int value = 5;
struct btnode *l;
struct btnode *r;
};
int test(int *p)
{
printf("%d", &p->value);
}
int main()
{
int *asdf = (int *)malloc(sizeof(struct btnode));
test(asdf);
}
Here is a mod of your program which allocates memory for one struct, fills in values for its members, and calls test() to print one member.
#include <stdlib.h>
#include <stdio.h>
struct btnode
{
int value;
struct btnode *l;
struct btnode *r;
};
void test(struct btnode *p)
{
printf("%d", p->value);
}
int main(void)
{
struct btnode *asdf = malloc(sizeof *asdf);
if(asdf != NULL) {
asdf->value = 5;
asdf->l = NULL;
asdf->r = NULL;
test(asdf);
free(asdf);
}
return 0;
}
There are a number of small changes to detail too, I leave you to spot the differences.
First of all there are some mistakes in the code.
1) You can not assign values in the structure.
2) When you are making a pointer for the structure you need pointer of the structure not of the int (does not matter what you want from the inside of the structure)
This is the modified code which runs perfactly
#include<stdio.h>
struct btnode
{
int value;
struct btnode *l;
struct btnode *r;
};
int test(struct btnode *p)
{
printf("%d", p->value);
}
int main()
{
struct btnode *asdf = (struct btnode*)malloc(sizeof(struct btnode));
asdf->value = 5;
test(asdf);
}

Random Queue in C

I've written this code with all correct understandings i have. please check my problems.
#include<stdio.h>
#include<stdlib.h>
// Define a structure for the dequeue elements
This structure is all good, with data, next, previous pointers.
typedef struct RanElmt_ {
void *data;
struct DeqElmt_ *prev;
struct DeqElmt_ *next;
void (*destroy)(void *data);
//Your Code here
} RanElmt;
THis is ok too, acording to what i think is correct.
typedef struct RandQ_{
int size;
struct RanElmt *head;
struct RanElmt *tail;
}RandQ;
RandQ * RandomizedQueue(void (*destroy)(void *data)){
RandQ *relmt = (RandQ*)malloc(sizeof(RandQ));
} // construct an empty randomized queue
int isREmpty(RandQ *rQ){
if ( rQ->size == 0)
return 1;
return 0;
} // is the queue empty?
int rsize(RandQ *rQ){
return rQ->size;
}
// return the number of items on the queue
ACtually this is only one function,(enqueue) I'm going to get the idea and code other functions(dequeue, sample etc..)
int enqueue(RandQ *rQ, const void *data){
RanElmt *relmt = (RanElmt*)malloc(sizeof(RanElmt));
relmt->data = (void*)data;
if (rQ->head == NULL){
relmt = rQ->head;
relmt = rQ->tail;
relmt->prev = NULL;
relmt->next = NULL;
}
else{
rQ->head = relmt;
}
(rQ->head)->prev = relmt;
relmt->prev = rQ->head;
rQ->head = relmt;
} // add the item
main(){
Deque(free);
printf(" okk \n");
}
THis program is giving these errors:
Errors i'm getting
In C struct tags and type names live in different name spaces. That is struct RanElmt and RanElmt are two different types, in addition struct RanElmt is not completely defined.
Your RandQ should be defined something like
typedef struct RandQ_{
int size;
struct RanElmt_ *head; // or RanElmt* head;
struct RanElmt_ *tail; // or RanElmt* tail;
}RandQ;
in addition your RanElmt is probably not what you want, maybe you meant:
typedef struct RanElmt_ {
void *data;
struct RanElmt_ *prev; // pointer to a struct of the same type
struct RanElmt_ *next; // pointer to a struct of the same type
void (*destroy)(void *data);
// You cannot put code here in C (or even a function definition AFAIK).
} RanElmt;
You have confused the struct tag and the typedeffed alias for the queue elements in the definition of the queue:
typedef struct RandQ_{
int size;
struct RanElmt *head;
struct RanElmt *tail;
} RandQ;
Here, the head and tail are of the type struct RanElmt. This struct doesn't exist in your program. You have a struct RanElmt_ (with trailing underscore) that you can also call ´RanElmtwithout thestructkeyword, because you have combined the struct definition with atypedef`.
The compiler still generates the code, because pointers to unknown structs are okay, unless you try to get at their data. Obviously the compiler can't access the struct fields if it doesn't know them.
There's no need for the underscore. The names of structs are in a separate namespace, so you can have both a struct called RandQ and a type (in global namespace) called RanQ. I recommend to use the same name for struct tag and aliassed type.
You can also get rid of the need to use the struct keyword inside the struct defnition if you separate the typedef from the struct definition:
typedef struct RanElmt RanElmt; // use just RanElmt from now on
struct RanElmt {
void *data;
RanElmt *prev;
RanElmt *next;
} RanElmt;
Your code has several other problems, but I think he program is in an early state, so I don't address them here.

malloc structure C

I can't understand why this litle code doesn't work ! i get it from C struct and malloc problem (C) (selected answer) and I wonder why it doesn't work for me.
any idea ?
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(tree)); /* different names for variables */
node* anode = malloc(sizeof(node));
atree->nodes[0] = anode; // <-------- SEG FAULT HERE !
return atree;
}
int main() {
tree* mytree = initTree();
return 0;
}
With a call to
tree* atree = malloc(sizeof(tree));
you have allocated a memory for tree object, so for a struct node** nodes pointer to (as it is a struct member), but it doesn't point to valid memory yet. You have to allocate also a memory for the nodes to which it is supposed to point to. For example:
atree->nodes = malloc( atree->numNodes*(sizeof (node*)));

Learning C - Compiling error allocating pointers

I'm new to C and trying to compile this simple code, but it's not working and I'm not sure why. Can anyone help me?
int main(int argc, const char * argv[])
{
struct Node{
int value;
struct Node *next;
};
struct Node* x;
struct Node* y;
struct Node* z;
x = malloc(sizeof(Node));
y = malloc(sizeof(Node));
z = malloc(sizeof(Node));
return 0;
}
The compiler is complaining about the use of an undeclared identifier ‘Node’:
x = malloc(sizeof(Node));
y = malloc(sizeof(Node));
z = malloc(sizeof(Node));
Welcome to SO and the wonderful world of C!
A few pointers for you:
Syntax-ically there's no problem with defining a struct inside a function, but typically it's defined outside so that it can be used in other functions. For example:
main(){
struct nodedef{vars};
add_to_node(node var);
}
add_to_node(node var)
{
// How can I add a to a node when I don't know what that is?
}
The main problem with your code is that you aren't correctly referencing your node later on, if I declaire:
struct me {
int i;
};
Then anytime I reference this type of struct, I have to explicitly say struct again:
struct me myself;
myself = malloc(sizeof(struct me));
myself.i = 5;
The way to avoid this reuse of the struct keyword is to use the typedef:
typedef struct me {
int i;
}m;
m myself;
myself = malloc(sizeof(m));
myself.i = 5;
Last point is anytime you allocate some memory via malloc() make sure you call free() to release that memory:
free(myself);
Or else you'll have a memory leak.
Try sizeof(struct Node) instead.
struct Node should be used to refer to the structure. If you want the code above works, an alternative is typedef-ing the struct Node structure as
typedef struct Node {
int value;
struct Node *next;
} Node;

Resources