Random Queue in C - 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.

Related

Making a generic linked list implementation that can be used with different sized structs

Hi I am currently working on a project where I am creating a very simple filesystem and I am working on some inode and general file cache implementations and I was wondering considering structs like this:
typedef struct disk_inode {
short type; /* file type */
short nlinks; /* number of directory entries referring to this file
int size; /* file size in bytes */
short inode_indir_idx;
/* pointers to the first NDIRECT blocks */
blknum_t direct[INODE_NDIRECT];
blknum_t indirect; /* The rest of the blocks */
}disk_inode_t;
struct cache{
short blocknr;
char block[512];
};
is there a way to create a generic list which can be used by both of these structures? This is in C and I cannot use any standard c libraries.
You can create a generic linked list which would take a void * as its element. Such implementation would require you to allocate your element in most cases though.
Here is a symple example:
typedef struct list_s
{
void *elm;
struct list_s *next;
struct list_s *prev;
} list_t;
typedef struct
{
int elem1;
int elem2;
int elem3;
} my_struct_t;
int main(void)
{
my_struct_t *elem = malloc(sizeof(my_struct_t));
list_t *list = malloc(sizeof(list_t));
list->prev = NULL;
list->next = NULL;
list->elm = elem;
return 0;
}

Dereferencing Pointer to incomplete type Linked List - C

I've been trying to figure this out for a while now, but cannot find a solution. I am building a linked list and when I try to pass the list as a pointer to anything I get an error: Dereferencing Pointer to incomplete type.
Here is my struct declaration
typedef struct listStruct{
char *name;
int size;
boolean inRestStatus;
list *next;
}list;
and one of the many functions that do not work.
void addToList(list *l, char * name, int size){
list *tmp;
while(l->next != NULL){
l = l->next;
}
tmp = malloc(sizeof(list));
tmp->name = name;
tmp->size = size;
tmp->inRestStatus = NO;
tmp->next = NULL;
l->next = tmp;
}
and the header
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct listStruct list;
I have tried changing the struct declaration to
typedef struct listStruct list{
...
};
and received the error: request for member in something not structure or union.
If anyone has any ideas that'd be awesome.
Edit
The struct definition is/was in a main function in a seperate file than the function, I have since moved the definition to the header file.
It seems that you declared only typedef name in the header
typedef struct listStruct list;
Thus the module where function
void addToList(list *l, char * name, int size);
is defined does not know the definition of the structure.
You have to include the structure definition in the header as for example
typedef struct listStruct{
char *name;
int size;
boolean inRestStatus;
struct listStruct *next;
}list;
that it would be accessible in the module where the function is defined.
Take into account that this method
void addToList(list *l, char * name, int size){
list *tmp;
while(l->next != NULL){
l = l->next;
}
tmp = malloc(sizeof(list));
tmp->name = name;
tmp->size = size;
tmp->inRestStatus = NO;
tmp->next = NULL;
l->next = tmp;
}
is also wrong. For example l can be equal to NULL can't it?
Also simple copying pointers
tmp->name = name;
looks questionably. Should you allocate memory to store a copy of a string pointed to by argument name?
Apparently, you placed your struct declaration into some implementation file, and a wrong implementation file at that.
The typedef declaration that you have in your header
typedef struct listStruct list;
declares an incomplete type. You have to place this
typedef struct listStruct{
char *name;
int size;
boolean inRestStatus;
list *next;
} list;
into the header or at least into the same implementation file that uses the data fields of your struct. Where is it now? You have to describe your file structure in full detail.

Dereferencing pointer to incomplete type(with well defined structs) in C

I know there are at least 10 questions already about this, but they all point to something I am not doing.
In a header file I have...
typedef struct Node {
struct Node *next;
struct pgmap page;
} Node;
typedef struct linkedlist {
struct Node *head_ptr;
struct Node *tail_ptr;
} LList;
In my c file I have
struct LList mainList;
int main()
{
struct LList *root;
root = &mainList;
root->head_ptr = NULL;
root->tail_ptr = NULL;
...
}
On the root-> lines I get the dereferencing ptr... error. All the threads already on here point to a problem where people accidentally create anonymous structs, such as
typedef struct{
int a;
}; monkey
instead of
typedef struct monkey{
int a;
}; monkey
So what am I missing????
There is no type called "struct LList". The code "typedef struct linkedlist { ... } LList;" creates two type names: one is struct linkedlist, and the other is just LList (without "struct"). You thus need to change "struct LList" to "LList."

How to free a struct that is inside an other struct

I have the following two structs:
typedef struct label{
int id;
double p,*t,q,c;
int V[45];
struct label *next;
struct label *prev;
struct path *tail;
struct path *head;
}label;
typedef struct path{
int i;
struct path *Pperv;
struct path *Pnext;
}path;
void main (){
int i,j;
struct label *Current,*Head,*Tail;
struct path *test1,*path_head,*path_tail;
Head=(struct label*)malloc(1*sizeof(struct label));
Tail=(struct label*)malloc(1*sizeof(struct label));
Head->next=Tail;
Tail->prev=Head;
for (i=0;i<250000;i++)
{
Current=(struct label*)malloc(1*sizeof(struct label));
Current->t=(double*)malloc(15*sizeof(double));
Current->head=(struct path*)malloc(1*sizeof(struct path));
Current->tail=(struct path*)malloc(1*sizeof(struct path));
Current->head->Pnext=Current->tail;
Current->tail->Pperv=Current->head;
for (j=0;j<15;j++)
{
test1=(struct path*)malloc(1*sizeof(struct path));
test1->Pperv=Current->head;
test1->Pnext=Current->head->Pnext;
Current->head->Pnext->Pperv=test1;
Current->head->Pnext=test1;
test1->i=1;
Current->t[j]=23123.4323334;
}
Current->next=Tail;
Current->prev=Tail->prev;
Tail->prev->next=Current;
Tail->prev=Current;
Current->p=54545.323241321;
}
}
I just used an example of filling some of the variables in them so that I can make my question. What I am facing problem with is how to free the struct "Path" that is contained into the the first struct called name "Label".
I would me sth more than greatful if somenone could give me the code of how to correctly free both structs in C.
In general, you just need to be symmetrical with the calls to malloc/calloc:
label *current = malloc(sizeof(*current));
current->head = malloc(sizeof(*current->head));
...
free(current->head);
free(current);

C union and struct question

I have a tree structure. The nodes would have a leaf node type and internal node type, so I defined these structures, so the internal node would be able to point to either internal nodes or leaf nodes. However, I am having trouble in accessing the child pointers, how can I do that, after all does my code make sense at all?
typedef struct leaf_node_t {
int type;
int key;
int *data_ptr[2]; //This will point to real data.
} leaf_node_t;
typedef struct internal_node_t {
int type;
int key;
typedef union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
} node_ptr;
} internal_node_t;
The typedef of node_ptr does not actually add a field to its enclosing struct. The following adds the fields first, and then follows up with the typedef. The other change I made was having the union represent a single pointer, leaving it to the struct that uses it to decide how many pointers it wants.
typedef struct internal_node_t{
int type;
int key;
union node_ptr_t {
struct internal_node_t* iptr;
leaf_node_t* lptr;
} node_ptr[2];
}internal_node_t;
typedef union node_ptr_t node_ptr_t;
Try this:
typedef struct leaf_node_t{
int key;
int *data_ptr[2];//this will point to real data
} leaf_node_t;
struct internal_node_t;
typedef union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
} node_ptr;
typedef struct internal_node_t{
int key;
node_ptr node;
} internal_node_t;
int main()
{
internal_node_t inode;
leaf_node_t* leaf_node = inode.node.lptrs[0];
return 0;
}
Alternately, if you don't actually need to use the union typedef anywhere else:
typedef struct leaf_node_t{
int key;
int *data_ptr[2];//this will point to real data
}leaf_node_t;
typedef struct internal_node_t{
int key;
union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
}node_ptr;
}internal_node_t;
int main()
{
internal_node_t inode;
leaf_node_t* leaf_node = inode.node_ptr.lptrs[0];
return 0;
}
You should add a flag in the internal_node to know what is the node_ptr, if it's an internal_node_t or a leaf_node_t. Probably a int isInternal[2]; (after the key and before the typedef). if it's 0 the it's internal, if it's 1 then it's leaf_node_t. C language doesn't have a typeof or a GetType to know what type of memory is pointed by a pointer (and C++ has it only if you are compiling with the RTTI "option" activated)

Resources