I've been struggling with this for a while, I can't seem to create a valid LinkedList data structure in C,
Here's all my structures:
typedef struct {
int size;
int *cellsI;
int *cellsJ;
} DataInList;
typedef struct listElement{
DataInList dataVar;
struct listElement *next;
} LinkedListElement;
typedef struct {
LinkedListElement*first;
LinkedListElement*last;
} LinkedListRoot;
I have a function that adds a data element to the linked list:
public void addDataToList(LinkedListRoot root, DataInList data) {
LinkedListElement newElem;
newElem.dataVar = data;
newElem.next = NULL;
if(root->first == NULL) {
root->first = &newElem;
root->last = &newElem;
} else {
root->last->next = &newElem;
root->last = &newElem;
}
}
Can anyone help me please?
As the commenter said, you've defined newElem in the function, and on the stack as well, so you have no way to globalize it or return a permanent entry to it. Something more along these lines. I haven't tested it yet, but it should give you the idea:
typedef listData struct {
int size;
int *cellsI;
int *cellsJ;
} listData_t
typedef struct listElement {
listData_t dataVar;
struct listElement *next;
} listElement_t;
typedef struct listRoot {
listElement_t *first;
listElement_t *last;
} listRoot_t;
listElement_t *
addDataToList(listRoot_t *root, listData_t *data) {
listElement_t *newElem = malloc(sizeof(struct listElement));
if (newElem == NULL) {
fprintf(stderr, "Error allocating memory\n");
exit(-1)
}
newElem->dataVar = data;
newElem->next = NULL;
if (root->first == NULL) {
root->first = newElem;
root->last = newElem;
} else {
root->last->next = newElem;
root->last = newElem;
}
return newElem;
}
Related
Below is the program
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
struct node* reverse_ll(struct node* hnode)
{
if(hnode == 0)
{
return 0;
}
if(hnode->next == 0)
{
head=hnode;
return hnode;
}
struct node* ptr=reverse_ll(hnode->next);
ptr->next=hnode;
hnode->next=0;
//return hnode;
}
void display()
{
struct node *ptr;
ptr=head;
if(ptr==0)
{
printf("empty");
}
else
{
while(ptr!=0)
{
printf("%d->",ptr->data);
ptr=ptr->next;
}
printf("null");
}
}
int main()
{
struct node* h;
lastinsert(1);
lastinsert(2);
lastinsert(3);
lastinsert(4);
lastinsert(5);
display();
h=reverse_ll(head);
display();
return 0;
}
In function reverse_ll() even if I comment "return hnode" I am getting the right output How is it possible where does ptr receives its address from when I comment "return hnode"?
output: 1->2->3->4->5->null
5->4->3->2->1->null
reverse_ll() must return a struct node * in the recursive case:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head;
void lastinsert(int data) {
struct node **c = &head;
for(; *c; c = &(*c)->next);
*c = malloc(sizeof(*head));
if (!(*c)) {
printf("malloc failed\n");
return;
}
(*c)->data = data;
(*c)->next = NULL;
}
struct node *reverse_ll(struct node* hnode) {
if(!hnode)
return NULL;
if(!hnode->next) {
head = hnode;
return hnode;
}
struct node *ptr=reverse_ll(hnode->next);
ptr->next=hnode;
hnode->next = NULL;
return hnode;
}
void display() {
if(!head) {
printf("empty");
return;
}
for(struct node *ptr = head; ptr; ptr = ptr->next) {
printf("%d->",ptr->data);
}
printf("null\n");
}
int main() {
for(int i = 1; i <= 5; i++) {
lastinsert(i);
}
display();
reverse_ll(head);
display();
// It's good practice to implement a function that frees you list
// which you would call here.
return 0;
}
and example run:
$ ./a.out
1->2->3->4->5->null
5->4->3->2->1->null
I am quite new to C and having a lot of trouble with generic linked lists in c.
Im trying to convert my linked list into a generic one but I don't really understand how to.
This is my original one:
typedef struct LLNode {
int rowPos;
int colPos
char Charecter
struct LLNode *next;
} LLNode;
typedef struct LinkedList {
LLNode *head;
LLNode *tail;
int ROW;
int COL;
int appleCount;
int winCon;
int snakeSize;
} LinkedList;
I understand that the data has to be a void but can you have more than one void *data; in a node.
So far I have this:
typedef struct LLNode {
void *data;
struct LLNode *next;
} LLNode;
typedef struct LinkedList {
LLNode *head;
LLNode *tail;
int ROW;
int COL;
int appleCount;
int winCon;
int snakeSize;
} LinkedList;
But I don't know how I go about accessing and changing 3 lots of data in one void *data.
You can use macros:
#define LNODE(Type) LNode_ ## Type
#define LLIST(Type) LList_ ## Type
#define DECL_LINKED_LIST(Type) \
typedef struct LNODE(Type) { Type value; struct LNODE(Type)* next; } LNODE(Type); \
typedef struct LLIST(Type) { LNODE(Type)* head; LNODE(Type)* tail; } LLIST(Type);
typedef struct {
char const* f_name;
char const* l_name;
} Person;
DECL_LINKED_LIST(Person);
int main() {
LLIST(Person) list;
LNODE(Person) node1;
list.head = list.tail = &node1;
node1.next = 0;
node1.value.f_name = "John";
node1.value.l_name = "Smith";
}
It's somewhat ugly, but it works. Alternatively, if you can use a C++ compiler instead, you can use templates.
C does not have typed generic aggregates such as C++ templates, but you can implement simpler aggregates pointing to data items via void * pointers. You can also use macros to mix the data and the aggregation internals, but it requires more advanced C skills.
Here is an example using void * for data:
#include <stdio.h>
#include <stdlib.h>
/* generic list handling */
typedef struct LLNode {
struct LLNode *next;
void *data;
} LLNode;
typedef struct LinkedList {
LLNode *head;
LLNode *tail;
} LinkedList[1];
void LinkedList_init(LinkedList list) {
if (list) {
list->head = list->tail = NULL;
}
}
void *LinkedList_append(LinkedList list, void *data) {
if (list) {
LLNode *node = malloc(sizeof(*node));
if (node != NULL) {
node->data = data;
node->next = NULL;
if (list->head == NULL) {
list->head = list->tail = node;
} else {
list->tail = list->tail->next = node;
}
return data;
}
}
return NULL;
}
void *LinkedList_delete(LinkedList list, void *data) {
if (list) {
for (LLNode **np = &list->head, *last = NULL; *np;) {
LLNode *node = *np;
if (node->data == data) {
if ((*np = node->next) == NULL)
list->tail = last;
free(node);
return data;
} else {
last = node;
np = &node->next;
}
}
}
return NULL;
}
void LinkedList_free(LinkedList list, int free_data) {
if (list) {
for (LLNode *node = list->head, *next; node; node = next) {
next = node->next;
if (free_data)
free(node->data);
free(node);
}
list->head = list->tail = NULL;
}
}
#define LinkedList_foreach(var, list) \
for (LLNode *np__ = (list)->head, *next__; np__ != NULL; np__ = next__) \
for (var = (next__ = np__->next, np__)->data; np__; np__ = NULL)
/* use a generic list for my data */
typedef struct MyData {
int rowPos;
int colPos;
char Character;
} MyData;
typedef struct MyList {
int ROW;
int COL;
int appleCount;
int winCon;
int snakeSize;
LinkedList list; // linked list of MyData items
} MyList;
MyList *MyList_alloc(void) {
MyList *lp = calloc(sizeof(*lp), 1);
LinkedList_init(lp->list);
return lp;
}
void MyList_free(MyList *lp) {
LinkedList_free(lp->list, 1);
free(lp);
}
MyData *MyList_add(MyList *lp, int row, int col, char c) {
MyData *dp = malloc(sizeof(*dp));
dp->rowPos = row;
dp->colPos = col;
dp->Character = c;
return LinkedList_append(lp->list, dp);
}
void MyList_delete(MyList *lp, MyData *dp) {
free(LinkedList_delete(lp->list, dp));
}
void MyList_print(MyList *lp) {
printf("{\n");
LinkedList_foreach(MyData *dp, lp->list) {
printf(" { %d, %d, '%c' }\n", dp->rowPos, dp->colPos, dp->Character);
}
printf("};\n");
}
void MyList_filter_diagonal(MyList *lp) {
LinkedList_foreach(MyData *dp, lp->list) {
if (dp->rowPos == dp->colPos)
MyList_delete(lp, dp);
}
}
int main() {
MyList *mylist = MyList_alloc();
MyList_add(mylist, 0, 0, 'A');
MyData *d1 = MyList_add(mylist, 1, 2, 'B');
MyList_add(mylist, 2, 2, 'C');
MyList_add(mylist, 3, 5, 'D');
MyList_print(mylist);
MyList_delete(mylist, d1);
MyList_print(mylist);
MyList_filter_diagonal(mylist);
MyList_print(mylist);
MyList_free(mylist);
return 0;
}
I am very new in c language and I am so sorry if my question is too basic.
I want to define a dictionary in c in which I have a list as the value of my keys. In other word, I like to have something like this is python in c:
my_dictionary = {1:{'name':'john','items':['item1','item2']},2:{'name':'bob','items':['item3','item4']}}
Then I like to have access to my defined dictionary as this:
my_item = my_dictionary[1]['items'].
I know this is very easy in python but for c, I could not find a good example for this. I am able to define simple dictionaries such as:
typedef struct dict_t_struct {
char *key;
void *value;
struct dict_t_struct *next;
} dict_t;
and I can easily add, remove, or print items from this dictionary using below functions:
dict_t **dictAlloc(void) {
return malloc(sizeof(dict_t));
}
void dictDealloc(dict_t **dict) {
free(dict);
}
void *getItem(dict_t *dict, char *key) {
dict_t *ptr;
for (ptr = dict; ptr != NULL; ptr = ptr->next) {
if (strcmp(ptr->key, key) == 0) {
return ptr->value;
}
}
return NULL;
}
void delItem(dict_t **dict, char *key) {
dict_t *ptr, *prev;
for (ptr = *dict, prev = NULL; ptr != NULL; prev = ptr, ptr = ptr->next) {
if (strcmp(ptr->key, key) == 0) {
if (ptr->next != NULL) {
if (prev == NULL) {
*dict = ptr->next;
} else {
prev->next = ptr->next;
}
} else if (prev != NULL) {
prev->next = NULL;
} else {
*dict = NULL;
}
free(ptr->key);
free(ptr);
return;
}
}
but the problem is that I need to have linked list as the values of my dictionary and an inner dictionary in my dictionary.
1 Your structure is json, you can't use the normal dictionary completely
2 If you need to store a list, you need to define the data structure of the list.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DICT_STRING 1
#define DICT_LIST 2
typedef struct list_node {
void* value;
struct list_node* next;
} list_node;
typedef struct list {
list_node* head;
} list;
typedef struct dict_entry {
int type;
char* key;
void* value;
struct dict_entry* next;
} dict_entry;
typedef struct dict_t {
dict_entry* head;
} dict_t;
dict_t* dictAlloc(void) {
dict_t* d = malloc(sizeof(dict_t));
d->head = NULL;
return d;
}
void dictDealloc(dict_t* dict) {
free(dict);
}
dict_entry* addItem(dict_t* dict, int type, char* key, void* value) {
dict_entry* de = malloc(sizeof(*de));
de->type = type;
de->key = key;
de->value = value;
de->next = dict->head;
dict->head = de;
return de;
}
dict_entry* getItem(dict_t* dict, char* key) {
dict_entry* de = dict->head;
while (de) {
if (strcmp(de->key, key) == 0) {
return de;
}
de = de->next;
}
return NULL;
}
int main(int argc, char** argv) {
dict_t* d = dictAlloc();
dict_entry* de;
list* l = malloc(sizeof(*l));
list_node* n = malloc(sizeof(*n));
n->value = "value";
l->head = n;
addItem(d, DICT_LIST, "key", l);
de = getItem(d, "key");
switch (de->type) {
case DICT_LIST: {
list* l = de->value;
printf("%s", l->head->value);
}
}
}
does anyone know how save a value into a binary tree on the left or right side?
for example we have 2 structs:
struct A
{
int a;
struct A *left;
struct A *right;
}
struct B
{
A *root;
}
and we have a function:
void insert(B *tree, int value)
{
if(tree== NULL)
{
tree= (B*) malloc (sizeof(B));
}
else if(tree!=NULL)
{
tree->root->a = value;
tree->root->left = NULL;
tree->root->right = NULL;
}
now we have the root...
but how to initiliase the value on the right and left side?
else if(tree->apointer->a< value)
{
tree->root->left = value // with & wont work cause is a pointer to integer
}
does anyone know ??
Thanks in advance
With tree= (B*) malloc (sizeof(B));, you create an object of type B, but you do not create an object of type A to which tree->root could point to. Accessing tree->root->a or the other members of root then is undefined behaviour;
You could write:
tree = malloc (sizeof(B));
tree->root = malloc(sizeof(A));
I think there is no sense to discuss your code.:) Even structure definitions are written without semicolons.
Taking into account these structure definitions
struct A
{
int value;
struct A *left;
struct A *right;
};
struct B
{
struct A *root;
};
and assuming that in main there is the following declaration of the tree
int main( void )
{
struct B tree = { NULL };
//...
then the function insert can be defined the following way
int insert( struct B *tree, int value )
{
struct A **node = &tree->root;
while (*node)
{
if (value < (*node)->value)
{
node = &(*node)->left;
}
else
{
node = &(*node)->right;
}
}
*node = malloc(sizeof(struct A));
int success = *node != NULL;
if ( success )
{
(*node)->value = value;
(*node)->left = NULL;
(*node)->right = NULL;
}
return success;
}
The function can be called like
insert( &tree, value );
or its call can be enclosed in an if statement
if ( insert( &tree, value ) ) { /*...*/ }
I am writing linked list in Xcode in C.
in fact I can append the first node to the list. And everything runs well.
However when I append the second to the list, Xcode shows me EXC_BAD_ACCESS error on the line of malloc() a new node.
I know this error caused by accessing NULL pointer, but I cannot find where is wrong.
Here is part of my code.
SinglyLinkedList.c:
void llist_node_append(SList *ptr, const void *datap)
{
struct llist *me = ptr;
struct node *newnodep;
newnodep = malloc(sizeof(struct node));
if (newnodep == NULL)
FatalError("No space to append new node.\n");
newnodep->datap = malloc(sizeof(me->elemsize));
if (newnodep->datap == NULL)
FatalError("No space to append new node.\n");
memcpy(newnodep->datap, datap, me->elemsize);
newnodep->next = NULL;
me->last->next = newnodep;
me->last = newnodep;
if (llist_is_empty(me))
me->head->next = newnodep;
}
void llist_travel(SList *ptr, node_proc_fun_t *proc)
{
struct llist *me = ptr;
struct node *curr;
for (curr = me->head.next; curr != NULL; curr = curr->next) {
proc(curr->datap);
}
}
main.c:
struct node {
void *datap;
struct node *next;
};
struct llist {
struct node *head;
struct node *last;
int elemsize;
};
typedef struct food_list {
char breakfast[20];
char lunch[20];
char dinner[20];
} FoodList;
void llist_print(void* elem)
{
FoodList *temp = elem;
printf("the breakfast is %s\nthe lunch is %s\nthe dinner is %s\n", temp->breakfast, temp->lunch, temp->dinner);
}
int main()
{
SList list = *llist_new(sizeof(FoodList));
FoodList UCSB = {
"milk and bread",
"beef",
"burger",
};
FoodList UCB = {
"apple",
"juice",
"eggs",
};
llist_node_append(&list, &UCSB);
llist_node_append(&list, &UCB);
llist_travel(&list, llist_print);
return 0;
}