I am writing a linked list implementation for a networking project I'm working on. It is split into two files: llist.h and llist.c. I include llist.h in several of the project files, and when compiling I link to library that I compiled which includes llist.c. Unfortunately I get a "multiple definitions" error for every method header in llist.h. ie:
../util//libdutil.a(llist.o): In function `LListContains':
llist.c:(.text+0x0): multiple definition of `LListContains'
../util//libdutil.a(llist.o):llist.c:(.text+0x0): first defined here
I'm not quite sure why I'm getting this error. It used to be fine, but this has started happening since I added one more method. Here is the entire h file:
#ifndef _LLIST_H_
#define _LLIST_H_
typedef struct _LinkedList
{
int length;
void* data;
struct _LinkedList* head;
struct _LinkedList* tail;
}* LinkedList;
LinkedList LListContains(LinkedList list, void* data, int (*cmp)(const void *, const void *));
void* getDataLList(LinkedList list);
LinkedList createLList(void* data);
void* getFromHeadLList(LinkedList list, int pos);
void* popHeadLList(LinkedList list);
void* popTailLList(LinkedList list);
LinkedList getNextLList(LinkedList current);
LinkedList getPrevLList(LinkedList current);
void addHeadLList(LinkedList list, void* data);
void addTailLList(LinkedList list, void* data);
void FreeLList(LinkedList list);
#endif
Thanks!
UPDATE: Okay, the problem seems to come from the following code snippet in one of the project files:
OPP_DIRECTION(getDirToXYPOS((XYPOS*)getFromHeadLList(memories[avID], 0), &curPos)))
Note that getFromHeadLList is the method that I added to llist.h and defined in llist.c. By simply commenting out that part and adding in a dummy parameter, ie:
OPP_DIRECTION(getDirToXYPOS(&curPos, &curPos)))
It compiles fine.
Most probably you have compiled your llist.c into your project as well as into the static library.
Related
I have been given some existing C code (a header file and some source code) for an implementation of a linked list and have been given a task to use that to implement a queue.
Here is part of the header file I have been given with relevant function descriptions:
/* List is a pointer to a list_t struct */
typedef struct list_t* List;
struct list_t {
void *data;
List next;
};
/* Pushes data as the new head of list. May be used to create a new list:
* new_list = push(NULL, data) */
extern List push(List list, void *data);
/* Pop the head off the list */
extern void *pop(List *list);
/* Return the length of the list */
extern int len(List list);
/* Returns a reversed copy of list */
List reverse(List list);
/* Prepend data to list and update list */
extern List prepend(List *list, void *data);
/* Append l1 to the end of l2 */
void append(List l1, List *l2);
/* Inserts data into the tail of list */
void insert(void *data, List *list);
/* Inserts data into the tail of list or position equal to the next element */
void insert_by(bool (*eq)(void *data, void *node), void *data, List *list);
/* Inserts data into the tail of list. Returns true if sucessful,
* false if it finds an element already equal to data */
bool insert_if(bool (*eq)(void *data, void *node), void *data, List *list);
/* Returns the node equal to aim in list, returns NULL if not found */
extern List find(bool (*eq)(void *aim, void *node), void *aim, List list);
/* Removes and returns the element equal to aim in list,
* returns NULL if not found */
extern void *del(bool (*eq)(void *aim, void *node), void *aim, List *list);
/* Returns a new list that passes the predicate p */
List filter(bool (*p)(void *data), List list);
/* Print list to f by applying print to each node that is not NULL */
extern void print_list(void (*print)(FILE *f, void *data), FILE *f, List node);
/* Free the memory allocated to each list node */
extern void free_list(List node);
I know that in order to implement a queue, I need at minimum two functions, enqueue() and dequeue(). I went ahead and created my own header file with these functions and a typedef for the queue, using the List type from the above header file:
//Queue.h
#include "list.h"
typedef List Queue;
//Add item to queue...
void enqueue(Queue q, void *data);
//removes and returns an item from the queue...
void dequeue(Queue *q);
I then went ahead and implemented the source code in queue.c. I only implemented enqueue for now since I wanted to make sure that it worked before moving on:
#include "queue.h"
void enqueue(Queue q, void *data){
if (q == NULL){
q = push(q, data);
}
else {
insert(data, &q);
}
}
Really simple, I know. I planned to use the following file, main.c to test the queue:
#include <stdio.h>
#include "queue.h"
int main(int argc, char **argv){
Queue q = NULL;
int i;
for (i = 0; i < 10; i++){ enqueue(q, &i); } //one line for brevity
return 0;
}
At this point I didn't expect to see any output when I ran main.c, all I expected was for the program to run with no errors and then stop. Everything compiled fine, however when I ran main.c all I got was:
sh: ./main.exe: bad file number
What does this mean and can anybody pinpoint what could be causing this problem?
EDIT: Source code was compiled as such:
gcc -c list.c
gcc -c queue.c
gcc -c main.c -o main.exe
Your enqueue function breaks the contract of the push method.
The pushmethod returns the new head.
You would need:
Queue enqueue(Queue q, void *data){
return push(q, data);
}
And in your call:
for (i = 0; i < 10; i++){
q = enqueue(q, &i);
}
Note, however that this will push the same pointer every iteration. If you change i you will change the value of every node in the Queue. This is probably not what you want!
Also note that queueing the adress of a local (auto) variable is probably a bad thing and can lead to stack problems when the variable goes out of scope. (In your case i is declared in main, so it won't go out of scope until the program ends.)
This is not exclusively about a C programming problem but about the compiler commande not invoked correctly.
Your compile commands are incomplete.
Use this:
gcc -c list.c
gcc -c queue.c
gcc -c main.c
gcc list.o main.o queue.o -o main.exe
./main.exe
Explanation:
gcc -c list.c produces list.o
gcc -c queue.c produces queue.o
gcc -c main.c produces main.o
gcc list.o main.o queue.o -o main.exe invokes the linker that links the .o files
together producing main.exe
./main.exe run the program
There may be other programming related issues in your C code.
I am learning to write programs in professional way. Like, by creating separate .C and .h file.i decided to write a simple code with structures but I am getting errors.
I have done these things :
/*---list.h file-------*/
#ifndef LIST_H
#define LIST_H
struct list{
int a;
struct list *next;
};
typedef struct list LIST;
LIST *pHead=NULL,*pCurrent=NULL;
void display(void);
#endif
/*---list.c file ---*/
#include "main.h"
void display()
{
pHead->a=100;
printf("%d",pHead->a);
}
/*----main.h file-----*/
#ifndef MAIN_H
#define MAIN_H
#include<stdio.h>
#include "list.h"
#endif
/*---main.c file---*/
#include "main.h"
void main(void)
{
LIST *New=pHead;
display();
printf("\n\n%d",New->a);
getch();
}
when i compile the code , I am getting following errors
1>main.obj : error LNK2005: _pCurrent already defined in list.obj
1>main.obj : error LNK2005: _pHead already defined in list.obj
can anyone please tell me what I am doing wrong ? Am I including something twice because of which I am getting redeclaration error ?
This is because you define things in your header, as opposed to merely declaring them.
This:
LIST *pHead=NULL,*pCurrent=NULL;
means that every C file that includes the list header, tries to create two global variables. When you then link these C files together, those variables collide. This is broken, you should never do that. Never define things in a header.
You defined the objects in a header file and then included them in multiple source files thus breaking the one definition rule.
If you want to create global variables which you can use across different translation units, you should use the extern keyword.
Generally speaking, .c files contain embodiment of variables, functions, etc.; while .h files contain prototypes of variables, functions, etc., found in it's companion .c file.
It is generally the case that variable and function bodies are not placed in a .h file; only variable and function prototypes should be placed in .h files.
When considering how to split-up code into separate files, it is important to consider which functions, structures and macros are the most primitive. For example, if you write two functions, and function 'a' calls function 'b', function 'b' is most primitive.
The idea is to group functions into a 'c' file that are related, and are at a similar primitive level.
In the case of this question, the more primitive list functions should be embodied in list.c. Then 'list.h' is used to prototype functions and structures used by other less primitive .c files such as main.c.
The most primitive functions are also the most self sufficient. While less primitive functions should call more primitive functions, the reverse makes for clumsy code-flow.
Now to review the question code:
/*---list.c file ---*/
#include "main.h"
list.c should be considered as more primitive than main.c. Hence, having list.c include main.h is (professionally) not a good idea. list.c, being more primitive should be more self-sufficient.
Rather than including main.h, it would be better for list.c to include it's own list.h so that it has access to it's own `struct list' definition, etc.
void display()
{
pHead->a=100;
printf("%d",pHead->a);
}
In order to better isolate list.c, the above function should not reference a 'global' variable (pHead). Rather, it would be better to have the 'node to display' passed into the function as an argument.
With this in mind, here are how 'list.c' and 'list.h' might be improved:
/*---list.h file-------*/
#ifndef LIST_H
#define LIST_H
typedef struct NODE_S
{
int a;
struct list *next;
} NODE_T;
typedef struct LIST_S
{
NODE_T *head;
} LIST_T;
extern void NodeDisplay(NODE_T *node);
#endif
/*---list.c file ---*/
#include <stdio.h> // printf()
#include "list.h" // NODE_T, LIST_T
void NodeDisplay(NODE_T *node)
{
printf("%d\n",pHead->a);
return;
}
Note that pHead and pCurrent are not prototyped, or embodied, in list.h or list.c Those variables are not used in list.c, and there is no functional reason to place them in list.h
Now examine main.h and main.c as they are in the question code:
/*----main.h file-----*/
#ifndef MAIN_H
#define MAIN_H
#include<stdio.h>
#include "list.h"
#endif
In isolation, what is the purpose that main.h requires stdio.h and list.h? If they were removed, would there be something left 'undefined' in 'main.h'? Perhaps these two include files don't really belong in main.h. "But if they are removed from main.h, why even have a main.h?" Good point. perhaps main.h serves no purpose and perhaps should not even exist.
The main.c file is the least primitive of all files, and shouldn't generally export anything to other (more primitive) files.
/*---main.c file---*/
#include "main.h"
void main(void)
{
LIST *New=pHead;
display();
printf("\n\n%d",New->a);
getch();
}
So what exactly does main.c need? It needs calls printf(), so it will need to include stdio.h. It calls display(), and references the LIST structure, so it needs list.h.
Yes, those .h files were included in main.h; good point. However, the code will be less clumsy (more professional) if main.c includes exactly what it needs explicitly.
With this philosophy in mind, here is a reworked main.c, without a superfluous main.h:
/*---main.c file---*/
#include <stdio.h> // printf()
#include <conio.h> // getch()
#include "list.h" // NodeDisplay(), LIST_T
int main(void)
{
LIST_T pList =
{
.head = NULL
};
/* Allocate & Insert a node into the list. */
NodeCreate(&pList, 100);
NodeDisplay(pList.head);
getch();
return(0);
}
This version of main.c includes exactly what is required, and appropriately calls less primitive functions. It has no need for 'global variables' because it passes its local storage to more primitive functions as needed.
Oh! you noticed the function NodeCreate()!
While the operation of allocating and inserting a new list node could be performed in main.c, such an operation is most likely a common occurrence that fits nicely with other linked list operations. Hence, add such a function to list.c:
/*---list.c file ---*/
#include <stdio.h> // printf()
#include <stdlib.h> // malloc()
#include "list.h" // NODE_T, LIST_T
void NodeDisplay(NODE_T *node)
{
printf("%d\n",node->a);
return;
}
void NodeCreate(LIST_T *list, int a)
{
NODE_T *newNode = malloc(sizeof(*newNode));
if(NULL == newNode)
{
fprintf(stderr, "malloc(newNode) failed.\n");
goto CLEANUP;
}
if(NULL == list)
{
fprintf(stderr, "Passing NULL as the list address not allowed.\n");
goto CLEANUP;
}
/* Initialize new node fields (payload) */
newNode->a = a;
/* Link newNode as new 'list head' node. */
newNode->next = list->head ? list->head->next : NULL;
list->head = newNode;
newNode=NULL;
CLEANUP:
if(newNode)
free(newNode);
return;
}
And so that this function can be called from the less primitive main.c, add a prototype of the function to list.h:
/*---list.h file-------*/
#ifndef LIST_H
#define LIST_H
typedef struct NODE_S
{
int a;
struct list *next;
} NODE_T;
typedef struct LIST_S
{
NODE_T *head;
};
extern void NodeDisplay(NODE_T *node);
extern void NodeCreate(LIST_T *list, int a);
#endif
See spoiler code here.
I have a struct my_struct I found a guide saying there is a linked list that is really easy to use, all I need to do is include a task list_head in my struct, but I don't understand how to traverse this list correctly because I don't know how the list is actually structured
[edit] How does this kernel link list actually work? Please explain.
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
try this outside of kernel:
#include "list.h"
// my list of elements
struct my_struct
{
struct task list_head;
}
I then declare the head of my list:
struct my_struct *head;
Memory is malloc for the head like this:
head = malloc(sizeof(*head));
I could use something like;
int count_elements_in_list()
{
int size = 0;
struct my_list *pos;
list_for_each(pos, head)
{
size++;
}
return size;
}
Can someone explain how this linked list actually works?
In your code, you included "module.h"; which is a standard include module for most all Linux kernel modules. The "module.h" file includes "list.h".
(These include headers can be found under /usr/src/linux/)
-
The 'list.h' kernel header file defines the -only- acceptable linked list implementation for the Linux kernel (as per kernel.org folks). In tern, 'list.h' includes 'types.h', which define the following:
struct list_head {
struct list_head *next, *prev;
}
In the code supplied to your question:
struct task list_head;
'struct task' contains a 'struct list_head' element. Then later:
list_for_each()
which is defined in 'list.h', which requires uses 'pos' and 'head' to iterate the list.
The structure:
#include <gtk/gtk.h>
#include "db_interface.h"
struct AddNewEmployee {
const gchar *fname;
const gchar *lname;
};
void new_emp_get_data(GtkWidget *widget, gpointer add_emp_window)
{
struct AddNewEmployee n_e_s; //new employee struct
<gtk portion removed to clean code>
n_e_s.fname=gtk_entry_get_text(GTK_ENTRY(first));
n_e_s.lname=gtk_entry_get_text(GTK_ENTRY(last));
db_add_new_emp(&n_e_s); //pass the struct to db_interface to add new employee
}
The header file (db_interface.h)
#ifndef DB_INTERFACE_H
#define DB_INTERFACE_H
struct AddNewEmployee *n_e_s;
void db_add_new_emp(struct AddNewEmployee *n_e_s);
#endif
The second module (db_interface.c)
#include <stdio.h>
#include "db_interface.h"
void db_add_new_emp(struct AddNewEmployee *n_e_s)
{
printf("Greetings from db_interface, %s\n", n_e_s->fname);
}
When I try to compile the code using GCC, I get the message "error: dereferencing pointer to incomplete type". I have tried several different answers I found when others posted their problems with this error, but have yet to find one that works. I copied the code in the function from the db_interface.c module to the original module - the one containing the struct - and it worked fine, so I know my problem lies with sending the structure to the db_interface.c module.
Just move the struct AddNewEmployee to db_interface.h and it should compile just fine.
Both .c files need to know how the struct is implemented.
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 tried to create my tree program using this principle. 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 may be having problems because you haven't yet got a strong reason to split things up. A good reason would help you identify which parts belong together, and which parts are separate. So start with a simpler approach.
Split the program into three files, main.c, which contains main(), node.h, the header which ensures declarations are common across all the program, and hence is understood by the compiler, and node.c, the functions which manipulate the NODE structure.
Put the typedef ... NODE; and all the declarations of functions which manipulate NODE into one the node.h header file. So you could merge the existing header files into one, and call it node.h.
As Joop Eggen recommends, put #ifndef _NODE_H_ ... #endif around node.h contents to protect it against accidentally being #included twice.
Test that file is correct with a minimal main.c file containing:
#include "node.h"
int main() { return 0; }
and compile it. That should give no compilation errors. If it contains errors the fault is in the header file.
Put the functions that manipulate NODE, into a file called node.c, which will initially be:
#include "node.h"
compile and link that with main.c (gcc main.c node.c), and there should be no errors.
Build up the program is stages, adding code to the main.c file, the node.c file, and add declarations of functions in the node.c file into node.h. Add small amounts of code, and compile frequently (with warnings switched on, e.g. gcc -Wall main.c node.c) and test to make sure it is doing what you expect.
The program will eventually be complete.
I recommend looking at What are extern variables in C?.
You can include system headers such as <stdio.h> without having to worry about whether there are other headers needed to make use of its services. You should design your own headers in the same way. You should also prevent errors if your file is included multiple times (whether accidentally or deliberately).
You have:
b_tree_ds.h
typedef struct node {
struct node* left;
struct node* right;
int key; // contains value
} NODE;
Up to a point, this is fine; you just need to wrap it in header guards so reinclusion does no damage.
#ifndef B_TREE_DS_H_INCLUDED
#define B_TREE_DS_H_INCLUDED
typedef struct node {
struct node* left;
struct node* right;
int key; // contains value
} NODE;
#endif /* B_TREE_DS_H_INCLUDED */
You note:
When I try adding 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.
Syntactically, extern, static, auto, register and typedef are all storage classes, and you can only have one storage class in a given declaration. That's why you get the multiple storage class error. The 'multiple definition' error will continue to be a problem until C2011 is widespread, and the header guards prevent that from being a problem. I think header guards will remain valuable even after C2011 is widely available.
traverse.h
void traverse_print (NODE* p);
As it stands, you can't simply write #include "traverse.h" to make use of its facilities. This is something to be avoided whenever possible. (See: Self-sufficent header files in C and C++,
What is a good reference documenting patterns of use of h files in C, and Should I use #include in headers.) Therefore, this should include b_tree_ds.h:
#ifndef TRAVERSE_H_INCLUDED
#define TRAVERSE_H_INCLUDED
#include "b_tree_ds.h"
extern void traverse_print(NODE *p);
#endif /* TRAVERSE_H_INCLUDED */
You could omit the header include guards on this header (assuming that b_tree_ds.h is self-protects), but it is simpler to be self-consistent in all headers.
There is one other possible technique that could be mentioned:
#ifndef TRAVERSE_H_INCLUDED
#define TRAVERSE_H_INCLUDED
typedef struct node NODE;
extern void traverse_print(NODE *p);
#endif /* TRAVERSE_H_INCLUDED */
This makes NODE into an opaque type; the user of the header traverse.h knows nothing about what's in a NODE. There are coordination issues to resolve that make this a less commonly used technique.
With these changes to the headers, then:
traverse.c only needs to include traverse.h (and should arguably include it before any other header to provide an automatic test of self-containment), but
If traverse.c includes both headers, there are no problems, regardless of the order in which they are included (and it doesn't matter if the repetition is direct or indirect).
Your main.c can include just traverse.h as shown and will be OK. With the original code, because main.c only included traverse.h and traverse.h did not include b_tree_ds.h, the code would not compile properly.
Forget about extern. In traverse.h you should include b_tree_ds.h. Some compilers have a pragma include once, but it does not hurt to surround the content of b_tree_ds.h with:
#ifndef B_TREE_DS_H
#define B_TREE_DS_H
...
#endif // B_TREE_DS_H
Look for compiler info on this case, and also on precompiled headers.
The above is a platform independent way of excluding content the second time.