So i have
struct node {
int number;
struct node *next;
struct deck{
int number;
struct deck *next;
};
};
I want to create a 2D linked list. How can i initialize something like this?
Thanks.
Something like this maybe ?
struct deck{
int number;
struct deck *next;
}
struct node {
int number;
struct node *next;
struct deck *decks;
};
struct node *current_node, *new_node;
struct deck *current_deck, *new_deck;
current_node = (struct node *) malloc (sizeof(struct node));
for (i=0; i<number_of_nodes-1;i++) {
current_deck = (struct deck* ) malloc (sizeof(struct deck));
current_node->decks = current_deck;
for (j=0; j<number_of_decks_in_node_i-1; j++) {
new_deck = (struct deck* ) malloc (sizeof(struct deck));
current_deck->next = new_deck;
current_deck = new_deck;
}
new_node = (struct node *) malloc (sizeof(struct node));
current_node->next = new_node;
current_node = new_node;
}
First of all, you need to take deck outside node. What you have is valid C++ but not C.
You could write something like this:
struct node {
int number;
struct node *next;
};
struct deck{
struct node* nodes;
struct deck* next;
};
using cartesian system, you can. (BTW, it's not yet working for me. Trying)
struct node(){
char data[10];
node *x_link;
node *y_link;
}
Related
I'm trying to free a double linked list and my question is if I also need to free all the data and pointers in every node. Thank you.
Function:
static void free_list(Room *head, Room *head2) {
Room *tmp = head;
Room *tmp2 = head2;
Room *store;
Room *store2;
tmp = head2;
tmp2 = head;
printf("\nFreeing trap list...\n");
sleep(2);
while (tmp != NULL) {
store = tmp->pNext;
free(tmp);
tmp = store;
}
printf("\nFreeing rooms list...\n");
sleep(2);
while (tmp2 != NULL) {
store2 = tmp2->pNext;
free(tmp2);
tmp2 = store2;
}
}
Structure:
typedef struct Room {
struct Room *forward;
struct Room *left;
struct Room *right;
struct Room *previous;
struct Room *pPrev;
struct Room *pNext;
Room_Type Room_Type;
bool emergency_call;
} Room;
So do I also need to free, in the example, the forward pointer and also the other types as well? head and head2 are two different pointers, each points to the start of two different lists.
This way of defining the container is very confusing:
typedef struct Room{
struct Room* forward;
struct Room* left;
struct Room* right;
struct Room* previous;
struct Room* pPrev;
struct Room* pNext;
Room_Type Room_Type;
bool emergency_call;
} Room;
Divide and conquer:
typedef struct Node {
struct Node* pPrev;
struct Node* pNext;
Room_Type Room_Type;
bool emergency_call;
} Node;
typedef struct List {
struct Node* pHead;
struct Node* pTail;
} List;
With this approach, one loop is enough:
void free_list(List *list)
{
Node *node = list->pHead;
while (node != NULL)
{
Node *next = node->pNext;
free(node);
node = next;
}
free(list);
}
I start learning linked list,so my question may be stupid :p . I noticed that in all the exercices, they only take one data element in the node( as below : int data).So i am asking can we define multiple data elements in one node.Otherwise why not?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* nextptr;
};
struct node* BuildList()
{
/* initialize node's pointers */
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
/* allocate three nodes in the heap*/
head = malloc(sizeof(struct node));
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
/* setup first node */
head->data = 1;
head->nextptr = second;
second->data = 2;
second->nextptr = third;
third->data =3;
third->nextptr = NULL;
return head;
}
Yes, int just make it easier for the examples. But in real life, the node will be something more useful. Example:
struct chair {
int nr_or_legs;
int weight_in_kg;
int height_in_cm;
};
struct chair_node {
struct chair data;
struct chair_node* nextptr;
};
or just:
struct chair_node {
int nr_or_legs;
int weight_in_kg;
int height_in_cm;
struct chair_node* nextptr;
};
This question sounds super confusing even for me, and it may seem obvious or already answered, but I have searched a lot and although I found interesting things, I didn't find an answer exactly for my question. Here is some C code that will show much better my doubt:
typedef struct Node_struct {
char keyLine[100];
int occurrences;
struct Node* leftChild;
struct Node* rightChild;
struct Node* parent;
} Node;
typedef struct Tree_struct {
Node* root;
} Tree;
int insertNode(Tree* myTree, Node* newNode) {
...
Node* currentNode = myTree->root;
...
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = (Node*)currentNode->leftChild;
}
...
}
Is this code correct? Since currentNode is of type Node*, and currentNode->leftChild is of type struct Node*, I had to cast (Node*)currentNode->leftChild so that it could be assigned to currentNode. But I am not sure if this is correct, necessary, or if there is a better way to do the same.
Similarly, I also have this:
Node* coverNode = NULL;
...
coverNode->leftChild = (struct Node*)newNode;
What should be written
Suppose the code in the question were written like this:
typedef struct Node { // Not Node_struct as in the question!
char keyLine[100];
int occurrences;
struct Node* leftChild;
struct Node* rightChild;
struct Node* parent;
} Node;
Then the name Node would be a synonym (alias) for struct Node. (For any typedef X Y;, Y becomes a synonym for type X — where in your case, X would be struct Node and Y would be Node.)
The cast in:
currentNode = (Node *)currentNode->leftChild;
would be unnecessary (but mostly harmless) because it would be a no-op — the types struct Node * and Node * would be two names for the same pointer type. Similarly for:
coverNode->leftChild = (struct Node *)newNode;
The cast would be unnecessary but (mostly) harmless. There would be a small risk of confusing people with the cast. It is better to avoid casts when possible, and these would be better written without the casts:
currentNode = currentNode->leftChild;
coverNode->leftChild = newNode;
What is written
typedef struct Node_struct {
char keyLine[100];
int occurrences;
struct Node* leftChild;
struct Node* rightChild;
struct Node* parent;
} Node;
Now we have three type names in play: struct Node_struct, struct Node, and Node. In this case, struct Node_struct and Node are synonyms, and struct Node is an incomplete structure type (or, at least, it is not completed by any code in the question). It is wholly unrelated to either struct Node_struct or Node except by the coincidence that it is referenced inside the structure.
With this notation, the casts are 'necessary' because you're converting between pointers to unrelated types (struct Node * and struct Node_struct *). Fortunately, there are rules that say all structure type pointers are inter-convertible and must have the same size and alignment requirements (C11 §6.2.5 Types ¶28 and §6.3.2.3 Pointers ¶7).
But you should drop the _struct part of Node_struct to make the rules of the first part of this answer apply. In C, it is (IMO) sensible to use:
typedef struct SomeTag SomeTag;
so that you can subsequently use SomeTag * etc. The first SomeTag is in the tags name space and does not conflict with the second SomeTag, which is in the ordinary identifiers name space. See C11 §6.2.3 Name spaces of identifiers.
See also:
Which part of the C standard allows this code to compile?
Does the C standard consider that there are one or two struct uperms_entry types in this code?
C style/C++ correctness — is struct, union, enum tag same as type name bad in any way?
In c++, when you say struct Node, Node [immediately] becomes a type. So, you could say:
struct Node {
char keyLine[100];
int occurrences;
Node *leftChild;
Node *rightChild;
Node *parent;
};
struct Tree {
Node *root;
};
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
But, in c, it is merely in the "tag" namespace and does not define a type. Thus, you want:
typedef struct Node {
char keyLine[100];
int occurrences;
struct Node *leftChild;
struct Node *rightChild;
struct Node *parent;
} Node;
typedef struct Tree_struct {
Node *root;
} Tree;
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
As an alternative, you can use a forward declaration:
// forward declaration
struct Node;
typedef struct Node Node;
struct Node {
char keyLine[100];
int occurrences;
Node *leftChild;
Node *rightChild;
Node *parent;
};
typedef struct Tree_struct {
Node *root;
} Tree;
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
Note that the struct name does not have to match the type name:
// forward declaration
struct Node_struct;
typedef struct Node_struct Node;
struct Node_struct {
char keyLine[100];
int occurrences;
Node *leftChild;
Node *rightChild;
Node *parent;
};
typedef struct Tree_struct {
Node *root;
} Tree;
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
To allow cross linking of your two structs, we could do:
// forward declaration
struct Node_struct;
typedef struct Node_struct Node;
struct Tree_struct;
typedef struct Tree_struct Tree;
struct Node_struct {
char keyLine[100];
int occurrences;
Node *leftChild;
Node *rightChild;
Node *parent;
Tree *tree;
};
struct Tree_struct {
Node *root;
};
int
insertNode(Tree *myTree, Node *newNode)
{
Node *currentNode = myTree->root;
if (caseSenCmpString(newNode->keyLine, currentNode->keyLine) == -1) {
currentNode = currentNode->leftChild;
}
}
struct node {
int x;
struct node *next;
};
void allocateMemory(struct node *some_node) {
some_node = malloc(sizeof(struct node));
}
In another function:
struct node add(struct node *root, struct node *thisNode, int value)
I try to call this:
allocateMemory(thisNode->next);
I get a runtime error. It does nothing.
Yet when I do the same thing as allocateMemory() in the said function, i.e:
thisNode->next = malloc(sizeof(struct node));
It does what it is supposed to do.
What am I doing wrong?
Here in that code :
void allocateMemory(struct node *some_node) {
some_node = malloc(sizeof(struct node));
}
You can write :
void allocateMemory(struct node **some_node) {
*some_node = malloc(sizeof(struct node));
}
And while calling :
allocateMemory(&thisNode->next);
You need to paas pointer to pointer.
When you have pointer, then you can change value which is that pointer pointing to, and when you want to change the actual pointer then you need go one step deeper.
Also function add shouldn't return value but pointer?
struct node {
int x;
struct node *next;
};
void allocateMemory(struct node **some_node) {
*some_node = (struct node*)malloc(sizeof(struct node));
}
struct node* add(struct node *root, struct node *thisNode, int value) {
allocateMemory(&thisNode->next);
thisNode->x = value;
root->next = thisNode;
return thisNode;
}
I trying to build a BST and insert nodes in it. However while creating a new node I keep getting exc_bad access error.What can be the reason? Here is my code:
struct Node *node_create(struct BSTree *bst,void *nodeKey, struct Value *nodeVal, struct Node *rightChild, struct Node *leftChild)
{
struct Node *node = malloc(sizeof *node);
nodeKey= malloc (sizeof (bst->key_size));
nodeVal = malloc(sizeof(bst->value_size));
size_t sizeKey = sizeof(nodeKey);
memcpy(node->key, nodeKey, sizeKey); // exc_bad access
size_t sizeVal = sizeof (nodeVal);
memcpy(node->val, nodeVal, sizeVal); // exc_bad access
node->right = rightChild;
node->left = leftChild;
return node;
}
struct Node {
void *key;
struct Value *val;
struct Node *left;
struct Node *right;
};
struct BSTree {
size_t key_size, key_alignment;
size_t value_size, value_alignment;
int (*compare_func)(void *, void *);
struct Node *root;
// ... Maybe some other stuff.
};
struct Value {
char name[10];
int id;
};
Without knowing what Node, looks like, I'd say, even though you've allocated for node, you've not allocated all the members (which appear to be pointers).
Change your code to something like:
// Allocate node
struct Node *node = malloc(sizeof *node);
// Now members
node->key = malloc (sizeof (bst->key_size));
// :
If you are passing in the key and value, then do a memcpy of those values to the above locations. But hard to say without further code...
Without looking at the Node structure, I would guess what you want to do is:
if node is defined as
struct Node {
void *key;
struct Value *val;
struct Node *right;
struct Node *left;
};
then
struct Node *node_create(struct BSTree *bst,void *nodeKey, struct Value *nodeVal, struct Node *rightChild, struct Node *leftChild)
{
struct Node *node = malloc(sizeof *node);
node->key = malloc(bst->key_size); /* No sizeof here */
node->val = malloc(bst->value_size);
memcpy(node->key, nodeKey, bst->key_size);
memcpy(node->val, nodeVal, bst->value_size);
node->right = rightChild;
node->left = leftChild;
return node;
}
As you don't check for the returns of the mallocs (which is a design choice that can e justified), you can even write it simpler that way.
struct Node *node_create(struct BSTree *bst,void *nodeKey, struct Value *nodeVal, struct Node *rightChild, struct Node *leftChild)
{
struct Node *node = malloc(sizeof *node);
node->key = memcpy(malloc(bst->key_size) , nodeKey, bst->key_size);
node->val = memcpy(malloc(bst->value_size), nodeVal, bst->value_size);
node->right = rightChild;
node->left = leftChild;
return node;
}
There are people that cringe at this style but I prefer to not dilute my code too much on redundancies.