How to make library for linked-list functions - c

I want to create static or dynamic library for linked list functions, but when I try to compile function files with gcc to get object file it gives me error ‘struct node’ declared inside parameter list
int GetNth(struct node* head, int index) & dereferencing pointer to incomplete type ‘struct node’ if(i == index) return head->data;. Not sure what's going on, may be because I haven't declared the structure in the file
#include <stdlib.h>
int count(struct node* head, int n) //counts the occurrence of n in the list
{
int c = 0;
while(head != NULL){
if(head->data == n) c+=1;
head = head->next;
}
return c;
}
But if I'll declare it inside this file, I think it'll violate 1 definition rule. What to do?
structure is declared in the main function as
struct node{
int data;
struct node *next;
}

Prior to using objects (you use it, when have access to its members) you must completely define them. So, to use struct node, declare it before its first appearance in the source code. It's the rule of C programming language.
Put the declarations into header file and include the file into source files if you want to create useful libraries, e.g.:
...
struct node
{
...
};
int count(struct node *head, int n);
...

Continuing from the comment, in your code, the compiler does not know what node is because you have not provided its declaration. You can provide a declaration including a typedef for convenience. The following code declares a typedef to struct _node {...} as node; and then declares two nodes (statically for simplicity reasons), iterates over the list, outputting the data values and then ends, e.g.
#include <stdio.h>
typedef struct _node {
int data;
struct _node *next;
} node;
int main (void) {
node n1 = {.data = 1},
n2 = {.data = 2, .next = NULL};
n1.next = &n2;
/* iterate over list outputting data values */
for (node *n = &n1; n != NULL; n = n->next)
printf ("%d\n", n->data);
return 0;
}
Example Use/Output
$ ./bin/llstatic
1
2
As mentioned, you can create a header file for your list and include your declaration of struct _node and the typedef there, or if you simply use node within this source-file, you can declare it here. Let me know if you have further questions.

The compiler tells you it does not recognize struct node. You need to Declare it first. Something like struct node; (decleration) or struct node{...}; (definition) and the error should go away. If you have already declared it in another file header.h, just add #include "header.h" in the start of your code
Since you want struct node to contain a field called data, you need to add it when you define the struct:
struct node{
int data;
}

Related

Scope and Linked Lists in C

I'm trying to get more comfortable building and using linked lists in C, and for the most part I think I have the basics down. However, I am running into problems in regards to Scope, specifically the linkage of a Pointer to a Pointer of structs.
In my linked_list.c implementation I am using a main function to test out and play around with the linked list functions I've built. But the eventual goal is to run Main from another file, and only reference the few functions I'd need externally from a header file.
The implementation I'm using right now DOES work, but it seems to rely on me declaring the struct list** inside my (temporary)) main function.
It's my understanding that if you declare a variable/pointer outside of a block, you can control the linkage to be internal, accessible to other functions in the file, using the static command. What I would like to be able to do is call a function like void initialize_list() from OUTSIDE the program and have it initialize this internally linked list**.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
int value;
struct node *next;
};
struct list {
struct node *head;
struct node *tail;
int size; // Maintains current size of list
};
static struct list** work_list;
void dirty_init(void){
struct list* new_list = malloc(sizeof(struct list));
new_list->head = NULL;
new_list->tail = NULL;
new_list->size = 0;
*work_list = new_list;
}
Running my dirty_init function returns a segfault.
The version of code that DOES work is quite similar, but it seems to rely on the **work_list being declared inside of my main function before passing it to initialize_list.
void initialize_list(struct list **out_list){
struct list* my_list = malloc(sizeof(struct list));
my_list->head = NULL;
my_list->tail = NULL;
my_list->size = 0;
*out_list = my_list;
}
int main(void){
int i;
struct list **work_list;
initialize_list(work_list);
}
This is all well and good, but it has the drawback of making my **work_list pointer internally linked to the Main block. Any ideas where I am going wrong trying to get the dirty_init function to work?
This here:
int main(void){
int i;
struct list **work_list;
initialize_list(work_list);
}
can't work. C is pass by value and you pass an uninitialized value, which is then used as a result pointer. Did you mean
int main(void){
int i;
struct list *work_list;
initialize_list(&work_list);
}
instead?

What's the use of 'typedef in C'?

There are 3 versions of a header file.
version 1:
typedef struct node
{
void* dataPtr;
struct node* link;
} NODE;
version 2: without old type name 'node' (typedef oldTypeName newTypeName)
typedef struct
{
void* dataPtr;
struct* link;
} NODE;
version 3: without typedef
struct
{
void* dataPtr;
struct* link;
} NODE;
According to C : typedef struct name {...}; VS typedef struct{...} name;,
version 1's defining 'node' is superfluous and I changed it to version 2 and it worked fine.
According to this answer again, when not using 'typedef', one cannot reuse 'NODE'.
However, codes that use this version 3 header file worked just fine. (NODE was used two three times.)
This is the code:
/* Create a list with two linked nodes.*/
#include <stdio.h>
#include <stdlib.h>
#include "version3.h" //Header file
int main (void)
{
//Local Definitions
int* newData;
int* nodeData;
NODE* node;
// Statements
newData = (int*)malloc (sizeof (int));
*newData = 7;
node = createNode(newData);
newData = (int*)malloc (sizeof (int));
*newData = 75;
node->link = createNode(newData);
nodeData = (int*)node->dataPtr;
printf ("Data from node 1: %d\n", *nodeData);
nodeData = (int*)node->link->dataPtr;
printf ("Data from node 2: %d\n", *nodeData);
return 0;
} //main
What's the use of 'typedef' in this situation? (assuming that here I reused NODE. -> if this assumption is not true, please tell me why. I'm not familiar with C language.)
The following code does not create a type. It creates an object named NODE that has an anonymous struct as it's type.
struct {
void* dataPtr;
void* link;
} NODE;
int main() {
}
I find it difficult to believe that the code in your question compiles.
typedef is used to give a new name to a type. When your third version of struct is used then it just declare NODE of type struct{ void* dataPtr; struct* link;}. Now what would you do if you have to declare another variable of same type as of NODE? There is only one option, you have to declare it along with NODE otherwise they are incompatible.
Two structure are compatible if they are declared at same time or if they are declared using structure tag or the same type name (using typedef).

Unable to get this data structure to work (newbie)

I'm pretty new to C, and I've been trying to make a program with this data structure:
struct node {
char command[100];
char prereq[100][80];
char *targ;
int isUpdated;
} Node;
However, whenever I try to implement it in the code, like this:
Node n = malloc(sizeof(*n));
I get compiler errors such as "nmake.c:13:31: error: unknown type name ‘Node’".
I've tried code such as:
typedef struct node *Node;
with similar results. What's wrong?
I think you are confused about what typedef does.
A declaration such as this one:
struct node { ... };
will define a type named struct node. Do not forget the word struct! If you say just node it will mean nothing (note that this is different in C++).
So now to create a local variable you do:
struct node x;
And to do a dynamic one:
struct node *px = malloc(sizeof(struct node));
Now, if you want to make an alias to the type, you use the same exact syntax than to create a variable, but you write typedef at the beginning of the declaration:
typedef struct node Node;
Or if you prefer the pointer type:
typedef struct node *PNode;
Then to create variables:
Node a;
Node *b = malloc(sizeof(Node));
PNode c = malloc(sizeof(Node)); //do not use sizeof(PNode) as it is useless here
Some people, as #WhozCraig says in the comments, and you seem to intend in the original code prefer to use the declaring variable for sizeof instead of the type:
Node *b = malloc(sizeof(*b));
PNode c = malloc(sizeof(*c));
Actually there is no real difference, other than the style, so pick your favorite!
Note that when defining the original struct you can use the same declaration to create variables or typedefs, but not both:
struct node { ... } a; //a is a variable
typedef struct node {...} b; //b is a type
Some people like to force the syntax and do something like this:
typedef struct node {...} Node, *PNode; //tree types in one line!
but personally I find this practice a bit dumb: don't typedef a pointer unless you want to hide the fact that it is a pointer.
What you probably want is:
typedef struct _node {
char command[100];
char prereq[100][80];
char *targ;
int isUpdated;
} Node;
/*
* This defines a structure named _node.
* To use it, you must add struct everytime, for instance:
* struct _node foo;
*
* It also defines a typedef named Node which is a synonym to struct _node - Node
*/
Node *n = malloc(sizeof(*n));
/*
* Because we want to dynamically allocate we need a pointer, so we declared it as a Node *
*/

Strange behavior of "node"

I am confused! Trying to create dynamic linked list and want to assign header by "malloc" function. From my code below compiler gives 2 error:
in main: [Error] node' undeclared (first use in this function) and
**In functionnewnode':** [Error] `node' undeclared (first use in this function)
#include <stdio.h>
#include <stdlib.h>
struct node{
int a,b,c,d;
struct node *next;
};
struct node * newnode(int, int, int, int);
int main(){
struct node *header;
header=(struct node *)malloc(sizeof(node));
int a,b,c,d;
a=11;
b=2;
c=4;
d=5;
header->next=newnode(a,b,c,d);
printf("\n\n");
system("PAUSE");
return 0;
}
struct node * newnode(int aa, int bb, int cc, int dd)
{
struct node *temp;
temp=(struct node*)malloc(sizeof(node));
temp->a =aa;
temp->b =bb;
temp->c =cc;
temp->d =dd;
temp->next=NULL;
return temp;
}
I appreciate any advice! thank you!
There is no type node. You have type struct node and that's the one you need to pass to the sizeof operator.
Firstly, as #icepack already noted, the type is named struct node, not node. So, sizeof(node) does not compile. You meticulously used struct node everywhere in your code except in those two spots with sizeof.
Secondly, consider using the
T *p = malloc(n * sizeof *p); /* to allocate an array of n elements */
idiom for memory allocation. E.g. in your case
temp = malloc(sizeof *temp);
I.e. don't cast the result of malloc and prefer using sizeof with expressions, not with type names. Type names belong in declarations. The rest of the code should be as type-independent as possible.
As mentioned by previous answers, you have to use struct node when referencing to your structure.
However if you just want to use the declarative name node you can do as following:
typedef struct _node{
int a,b,c,d;
struct _node *next;
} node;
Here you do not need to use struct before you reference a node
Edit: wrong syntax

How to make a structure extern and define its typedef

I'm trying to implement tree algorithms in C. I have declared a extern struct in a header file that is completely independent (b_tree_ds.h). Now I plan to import the file in all source files that want to use this struct. So I must declare it using extern in header.
Now the problem is thhat I want to define its typedef as well. the compiler gives error of multiple storage classes. How should I do that.
typedef extern struct node {
struct node* left;
struct node* right;
int key; // contains value
}NODE;
The actual problem is as follow, which I still can't fix???
I recently learnt how can we use multiple source files with header files to make code portable and hierarchical. In order to do so, I tired creating my tree program using this principal. Here are my files
b_tree_ds.h - This will contain a declaration of datastructure of node of a tree, which can be called to various functions implementing different functionality of the tree (which may be in different source files)
typedef struct node {
struct node* left;
struct node* right;
int key; // contains value
}NODE;
When i try adding a extern as in typedef extern struct node it gives a error of multiple storage class but if I miss it, I get error for multiple definitions.
Here are my other source files
traverse.h - contains declaration of traverse function
void traverse_print (NODE* p);
Here also I get error for unknown identifier NODE
traverse.c - contains definition to that function
#include <stdio.h>
#include "b_tree_ds.h"
#include "traverse.h"
void traverse_print(NODE* p)
{
if(p->left != NULL)
{
traverse_print(p->left);
}
if (p->right != NULL)
{
traverse_print(p->right);
}
printf ("\n%d",p->key);
}
Finally main.c
#include <stdio.h>
#include "traverse.h"
void main()
{
// input
NODE p;
printf("\nInput the tree");
input_tree (&p);
printf("\n\nThe tree is traversing ...\n")
traverse_print(&p);
}
void input_tree (NODE *p)
{
int in;
int c;
NODE *temp;
printf("\n Enter the key value for p: ");
scanf("%d", &in);
p->key =in;
printf ("\n\nIn relation to node with value %d",in);
printf ("Does it have left child (Y/N): ")
if ((c = getchar()) == Y);
{
//assign new memory to it.
temp = (NODE *)malloc(sizeof(NODE));
input_tree(temp);
}
printf ("\n\nIn relation to node with value %d",p->key);
printf ("\nDoes it have right child (Y/N): ")
if ((c = getchar()) == Y);
{
//assign new memory to it.
temp = (NODE *)malloc(sizeof(NODE));
input_tree(temp);
}
}
This is my first attempt to such practice, please suggest is the structuring of my program good or should I try something else.
You can't make a struct extern. Just define it in an include-guard protected header and include that header everywhere you need it.
EDIT for SquareRootOfTwentyThree
I use those therms in the following way:
A structure type definition describes the members that are part of the
structure. It contains the struct keyword followed by an optional
identifier (the structure tag) and a brace-enclosed list of members.
A structure declaration has the same form as a structure definition
except the declaration does not have a brace-enclosed list of members.
So "definition" is exactly what I meant.
In C, structures have no linkage, only objects and functions do. So you can write this:
// header file 'node.h'
typedef struct node_
{
/* ... */
} node;
extern node root_node;
Then provide an implementation somewhere:
// source file
#include <node.h>
node root_node;
In your header file declare node.h like this
#ifndef NODE_H
#define NODE_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct node {
struct node* left;
struct node* right;
int key; // contains value
}NODE;
#ifdef __cplusplus
}
#endif
#endif /* NODE_H */
you can include this header file in any c program and use it like
NODE* newNode = NULL;

Resources