When I learn data structures in C, I got an error but I couldn't solve. How can I solve this problem?
#include <stdio.h>
#include <stdlib.h>
struct n {
int x;
n * next;
};
typedef n node;
int main() {
node * root;
root = (node * ) malloc (sizeof(node));
root -> x=10;
root -> next = (node * ) malloc (sizeof(node));
root -> next -> x=20;
root -> next -> next = (node * ) malloc(sizeof(node));
root -> next -> next -> x=30;
iter = root;
printf("%d",iter->x);
iter = iter -> next;
printf("%d",iter->x);
return 0;
}
5 5 D:\Dev C\Projects\main.c [Error] unknown type name 'n'
12 7 D:\Dev C\Projects\main.c [Error] request for member 'x' in something not a structure or union
13 7 D:\Dev C\Projects\main.c [Error] request for member 'next' in something not a structure or union
17 2 D:\Dev C\Projects\main.c [Error] 'iter' undeclared (first use in this function)
In your code a type named n does not exist.
That is why you have the line typedef n node; to make a type.
In C, the type of your structure is struct n not n.
So you need
typedef struct n node; to make a new type named node.
Within your struct, neither n nor node exist yet.
So there you need to do
struct n * next;
The last of your errors (though not explicitly covered by your question) then can be fixed by defining iter first.
node * root;
node * iter;
Related
This question already has answers here:
What is self-referencing structure in C?
(3 answers)
Closed 3 years ago.
Can someone explain what we mean when we do, like what does struct Node* next do. does it create a pointer of type struct? any help and resources about structures in c would be helpful
struct Node {
int dest;
struct Node* next;
};
"struct" itself is not a type. "struct [tag]" is a type, for example "struct Node" in your code.
In your case you define a structure type. Every structure of that type will contain a pointer to another structure of that type as a member called "next".
This allows you to chain the structures together in a so called linked list. You store a pointer to the first structure in a variable, then you can follow the chain of links down to the structure you need.
For example, you can do
struct Node *start;
start = malloc(sizeof struct Node);
start->dest = 7;
start->next = malloc(sizeof struct Node);
start->next->dest = 13;
start->next->next = malloc(sizeof struct Node);
start->next->next->dest = 19;
printf("%d %d %d\n", start->dest, start->next->dest, start->next->next->dest);
free(start->next->next);
free(start->next);
free(start);
Please note that this code omits all error handling, in real code you have to handle the case when malloc returns NULL.
Also, in real code you would use such a structure in loops that traverse the chain, not directly as above.
As #Serge is pointing out in comments, is not a struct within a struct, is a reference (a pointer) to an object of the same type, an example:
#include <stdio.h>
struct Node {
int dest;
struct Node* next;
};
int main(void)
{
/* An array of nodes */
struct Node nodes[] = {
{1, &nodes[1]}, // next points to the next element
{2, &nodes[2]}, // next points to the next element
{3, NULL} // next points to null
};
/* A pointer to the first element of the array */
struct Node *node = nodes;
while (node) {
printf("%d\n", node->dest);
node = node->next; // node moves to the next element
}
return 0;
}
Output:
1
2
3
Of course, in my example there is no benefit in using a linked list, linked lists are useful when we don't know the number of elements before-hand.
Another example using dynamic memory:
struct Node *head, *node;
node = head = calloc(1, sizeof *node);
node->dest = 1;
while (more_elements_needed) {
node->next = calloc(1, sizeof *node);
node->next->dest = node->dest + 1;
node = node->next;
}
for (node = head; node != NULL; node = node->next) {
printf("%d\n", node->dest);
}
void AlternatingSplit(struct Node* source, struct Node** aRef,
struct Node** bRef)
{
/* split the nodes of source to these 'a' and 'b' lists */
struct Node* a ;
struct Node* b;
struct Node* current = source;
if(current){
a=current;
b=current->next;
current=b->next;
a->next=NULL;
b->next=NULL;
}
while(current) {
a->next=current;
b->next=current->next;
if(b)
current=b->next;
b=b->next;
a=a->next;
}
*aRef = a;
*bRef = b;
}
I am getting segmentaton fault here i dont know why pls help.
This question is to alternating split linkedlist nodes. I m using two pointers a and b and adding to it alternatingly but its giving error . pls help me
Like most linked-list rearrangement exercises, pointers to pointers make the job much, much easier. The point of this exercise it to flex your ability to change the next pointers without ever changing the data values of said-same. Pointers to pointers are an excellent way to do that in C.
This is especially trivial because you were already provided the target pointer-to-pointer arguments that we can reuse for building each list. How that works is best understood by demonstrating a technique for building a forward-chained linked list using a single head pointer and a pointer to pointer p:
struct Node *head, **pp = &head;
for (int i = 1; i <= 20; ++i)
{
*pp = malloc(sizeof **pp);
(*pp)->data = i;
pp = &(*pp)->next;
}
*pp = NULL;
Yes, it needs error checking, but the algorithm is what to focus on here. This code uses only pp to build the actual list. The rule is this: pp is a pointer to pointer to Node, and always holds the address of the next pointer to Node to populate. That's what pointers to pointers do: hold addresses of pointers. In this case pp initially holds the address of the head pointer. With each new node added pp takes the address of the next pointer of the previously just-added node. Makes sense, right? That will be the next pointer where we want to hang the next node. This process continues until we finish the loop. At that pointer pp holds the address of the last node's next pointer, which we set to NULL to terminate the list.
Now, knowing what we learned above, consider this:
void AlternatingSplit(struct Node* source, struct Node** a, struct Node** b)
{
while (source)
{
*a = source;
a = &(*a)->next;
source = source->next;
if (source)
{
*b = source;
b = &(*b)->next;
source = source->next;
}
}
*a = *b = NULL;
}
Example
A short example using both the forward-chaining build algorithm I showed first, and the split algorithm I showed after, appears below. Some utility functions for printing the list are included. I leave freeing the lists (there are two now, remember to walk both and free each node) as an exercise for you:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void AlternatingSplit(struct Node* source, struct Node** a, struct Node** b)
{
while (source)
{
*a = source;
a = &(*a)->next;
if ((source = source->next))
{
*b = source;
b = &(*b)->next;
source = source->next;
}
}
*a = *b = NULL;
}
void PrintList(struct Node const *p)
{
while (p)
{
printf("%d ", p->data);
p = p->next;
}
fputc('\n', stdout);
}
int main(void)
{
struct Node *head, **pp = &head;
for (int i = 1; i <= 20; ++i)
{
*pp = malloc(sizeof **pp);
(*pp)->data = i;
pp = &(*pp)->next;
}
*pp = NULL;
PrintList(head);
struct Node *a = NULL, *b = NULL;
AlternatingSplit(head, &a, &b);
PrintList(a);
PrintList(b);
return EXIT_SUCCESS;
}
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20
There are few errors in your code -
Trying to access node->next , without checking whether node exists or not .
Not tackling the corner cases depending on the length of linked list (i.e. if length (linked list) < 3 )
And then comes the blunder , you are trying to make the new linked lists and then in the end aRef and bRef is assigned to the last node in their respective linked lists.
Try to deal with these problems and for reference you can see the code below.
void AlternatingSplit(struct Node* source, struct Node** aRef,
struct Node** bRef)
{
struct Node* a,b;
struct Node* current = source;
if(current){
a=current;
b=current->next;
// moving 'current' one step at a time will secure the code from crashing for corner cases
current = current->next;
if(b)
current=b->next;
a->next=NULL;
b->next=NULL;
//link aRef bRef right here
*aRef = a;
*bRef = b;
}
else {
*aRef = source; // Null
*bRef = source; // Null
return;
}
while(current)
{
a->next=current;
a=a->next;
b->next=current->next;
b=b->next;
current=current->next;
if(b){
current = b->next;
}
}
b->next = NULL;
a->next = NULL;
}
Hope this will help .
Keep asking , keep growing :)
I'm trying to write a linked list, with the restriction being that the pointer inside of a node has to point to the next node's pointer. With this restriction, how would I ever access a variable inside of a node?
Say the node is defined
struct Node {
int val;
void *next;
}
but for every Node, say we have currentNode and nextNode, we make the void *next value
currentNode.next = &(nextNode.next);
How would you go about creating this and efficiently accessing each node?
You can get a pointer to the Node by subtracting the offset of next, using the offsetof operator.
struct Node *nextNode = (struct Node *)((char *)currentNode.next - offsetof(Node, next));
int nextVal = nextNode->val;
If you're using C99, which doesn't have offsetof() built in, you can use this traditional macro:
#define offsetof(st, m) ((size_t)&(((st *)0)->m))
It's technically undefined behavior (see Does &((struct name *)NULL -> b) cause undefined behaviour in C11?) but it generally works.
Use an appropriate struct so that the restriction is inherently satisfied:
struct Node {
void *next;
int val;
}
No explicit pointer arithmetic required.
I am implementing a link list as per your requirement. Hope this will help your. In this link list every pointer inside the node pointing to the next node pointer.
Please add these 3 header file at the top of your program stdio.h, memory.h and stdlib.h
struct Node {
int val;
void *next;
};
void main(void)
{
typedef struct Node NODE;
NODE *f,*p,*q = NULL;
int i = 1;
/* First create your first node here */
f = (NODE *)malloc(sizeof(NODE));
f->next = f;
f->val = 0;
p = f;
/* now lets create link list with 10 nodes */
while( i < 10 )
{
q = (NODE *)malloc(sizeof(NODE));
q->next = q;
q->val = i++;
p->next = q->next; /* first node is pointing to the next node pointer */
p = q;
}
/* search the link list and print its value */
p = f; /* now p is pointing to the first node of the link list */
i = 0;
/* first print the value of first node here */
printf("Node :%d and val = %d\n", i, p->val);
while(p->next != p)
{
printf("Node :%d and val = %d\n", i++, ((NODE *)(p->next))->val);
p = p->next;
}
}
output of this program;
Node :0 and val = 0
Node :1 and val = 1
Node :2 and val = 2
Node :3 and val = 3
Node :4 and val = 4
Node :5 and val = 5
Node :6 and val = 6
Node :7 and val = 7
Node :8 and val = 8
Node :9 and val = 9
1 #include<stdio.h>
2 #include<malloc.h>
3
4 typedef struct node_t{
5 int i;
6 struct node_t* link;
7 }node;
8
9 node* head = (node *)malloc(sizeof(node));
10
11 if(head == NULL){
12 printf("\n malloc for head node failed! \n");
13 }
14
15 int main(){
16 int i = 10;
17 node* temp = NULL;
18 temp = (node *)malloc(sizeof(node));
19 if(temp == NULL){
20 printf("\n malloc for temp node failed! \n");
21 }
22 else{
23 while(i<=10){
24 ;
25 }
26 }
27 return 0;
28 }
compilation error:
linked.c:9:1: error: initializer element is not constant
linked.c:11:1: error: expected identifier or ‘(’ before ‘if’
I'm trying a simple linked list programme. It's not fully completed. I'm getting a compilation error. Couldn't understand why this happened.
Since you're defining head as a global, its initializer needs to be a constant--basically, the compiler/linker should be able to allocate space for it in the executable, write the initializer into the space, and be done. There's no provision for calling malloc as you've done above during initialization--you'll need to do that inside of main (or something you call from main).
#include <stdlib.h>
void init() {
head = malloc(sizeof(node));
}
int main() {
init();
// ...
}
In this case, the code you have in main never actually uses head though, so you may be able to skip all of the above without a problem.
9 node* head = (node *)malloc(sizeof(node));
10
11 if(head == NULL){
12 printf("\n malloc for head node failed! \n");
13 }
These lines are not possible outside the main() because any function call or executable should be inside the main() function or any function called from main.
For linked.c:9:1: error: initializer element is not constant
Only function definitions or any global initialization is possible outside main() but initializer must be constant expression`.
You can declare the head as global but initialization is wrong.
Do it like this :
node * head =NULL // here initialization using constant expression
void function () // any function
{
head = malloc(sizeof(node));
}
For linked.c:11:1: error: expected identifier,
if statement cannot be outside any function.
In your case , put these lines inside main and problem solved
head is a global varibale. Global and static varibales must be initialized by constant expressions, i.e. literals. so you can't do
node* head = (node *)malloc(sizeof(node));
You can't use malloc() in global scope.
or
you can do like follow
#include<stdio.h>
#include<malloc.h>
:
node* head
:
:
int main(){
:
:
head = (node *)malloc(sizeof(node));
:
:
}
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_ **)