overcome the lack of polymorphism in C - c

I'm working on a project that strictly requires to realize two set of functions in C with same signature that can be used from a sigle .c test file. one set is for a data structure, the other one for a different and incompatible data structure.
Since in C there is no polymorphism is not possible to call a function that has two implementation with same signature in two different headers (.h) files and taking for granted that the call will be referred to the right implementation of the function that is actually capable of managing the right data structure.
Ok I know it seems impossible and contradictory but..that is it...
I have to merge two generic items that can be list or dynamic array
Update:
on List.h (dynamicArray is in another .h)
typedef struct Node{
void *data;
struct Node *next, *prevNode;
} Node;
//typedef struct declaration List
typedef struct List {
struct Node *top, *bot, *prev;
int size;
} List;
//in the dynamicarray.h file:
typedef struct dynamicArray{
void **array;
size_t size;
size_t capacity;
}dynArray;
//in the dynamicarray.h file:
void* merge(void *element1,void *element2, int parameters){
void * returner;
if (parameters==ARRAY) {
returner= Array_Merge(element1,element2); // expected to receive two arrays
}
else {
returner= List_Merge(element1,element2); // expected to reveice two lists
}
return returner;
}
Do you have any suggestion to accomplish this request?
Thanks.

You need to pass both, a pointer to your function and some handler function to the test, along with argument(s). In 'c' void * can be use in place of any pointer. Something like the following might work for you:
int mytest(void*(*function)(void *), int(*handler)(void *), void *arg) {
if (handler(function(arg)))
return OK;
return FAIL;
}
So, you just need to have separate handler functions for arrays and lists and pass them to the test function along with other params.
Answering your last comment
I can imagine some scheme as the following.
List list1;
dyArray array1;
MergedList outList;
MergedArray outArray;
...
void *getNextArrayElement(dynArray *array){...}
void *getNextListElement(List *list){...}
int mergeAsList(void* el, void *list){
if (el == NULL)
return 0;
ListMember *mmb = malloc(sizeof(ListMember));
mmb->el = el;
mmb->next = ((MergeList*)list)->head;
(MergeList*)mergeList->head = mmb;
return 1;
}
int mergeAsArray(void *el, void *array) {
if (el == NULL)
return 0;
if (((MergeArray *)array)->index) >= MAX)
return 0;
((MergeArray *)array)[((MergeArray *)array)->index++] = el;
return 1;
}
int mergeAsSortedArray(void *el, void *array){...}
...
test(getNextArrayEelement, mergeAsList, &arraty1, &outList);
test(getNextListEelement, mergeAsList, &list1, &outArray);
...
int test (void *(get*)(void*),
int (merge*)(void *m1, void *result),
void *in,
void *out) {
void *el = get(in);
int res = merge(el, out);
return res;
}

Function pointers are the means in which you accomplish this.
Function pointers are what you would use if, for example, you wanted to pass a function to a sort function that told the sort function how to compare two adjacent members. Such a comparison function allows you to provide a generalized sort function that will work on a collection of any struct, since you can change out the comparison function to accommodate any struct.
Consider the following sort code:
typedef struct node{
void* item;
struct node* next;
} Node;
// Just an ordinary bubble sort
void sort(Node *start, bool greaterThan(void* a, void* b))
{
int swapped, i;
Node *ptr1;
Node *lptr = NULL;
/* Checking for empty list */
if (start == NULL)
return;
do
{
swapped = 0;
ptr1 = start;
while (ptr1->next != lptr)
{
if (greaterThan(ptr1->item, ptr1->next->item))
{
swap(ptr1, ptr1->next);
swapped = 1;
}
ptr1 = ptr1->next;
}
lptr = ptr1;
}
while (swapped);
}
// Swap function used above
void swap(Node *a, Node *b)
{
void* temp = a->item;
a->item = b->item;
b->item = temp;
}
To use it, we just need to define a payload to put into Node* item and a sort function to tell it how to order the items:
typedef struct {
int book_id;
char title[50];
char author[50];
char subject[100];
char ISBN[13];
} Book;
// Comparison function.
bool bookGreaterThan(void* left, void* right)
{
Book* a = (Book*)left;
Book* b = (Book*)right;
return strcmp(a->title, b->title) > 0;
}
Finally, you would sort your list like so:
// Pass a pointer to the first node in your list, and a function pointer to your comparer.
sort(pointerToMyList, bookGreaterThan);
A complete example can be found here.
See also Is it possible to achieve runtime polymorphism in C?

Related

Is there a way to point to a struct member from a function pointer?

I'm doing a double linked list from scratch in C and was programming the iter(able) function.
However my struct has a bunch of fields and I don't necessarily want to mess with all when I call the function. I want to choose what member to alter in the function call.
typedef struct s_command
{
int argc;
char *argv[MAXARGS];
t_token *args;
char **envp;
t_builtin builtin;
void *input;
void *output;
struct s_command *next;
struct s_command *prev;
} t_command;
My obvious choice was having an int argument that gets caught by an if else (can't use switch) to pick what field I want.
As such:
void dll_iter(t_command *lst, int property, void (*f)(void *))
{
if (!lst || !property || !f)
return ;
while (lst)
{
if(property == 1)
f(lst->argc);
else if(property == 2)
f(lst->argv);
else if(property == 3)
f(lst->args);
...
lst = lst->next;
}
}
But I can't stop but wonder if C has any way to simplify this. Make it cleaner.
What I would really like was someting like:
void dll_iter(t_command *lst, void (*f)(void *))
where f would call directly the member it wants.
Is there any way to achieve this?
I don't know how this will go over with a school, because this relies on border-line language-lawyering. But if you want a generic iterating function, just abstract away the only thing that matters to it, the links.
struct link {
struct link *next;
struct link *prev;
};
struct command {
struct link link;
// other members...
};
And now you can write
dll_iter(struct link*, void (*f)(struct link*));
Because a pointer to structure shares an address with it's first member, f can convert internally to the concrete node type it cares about. Meanwhile, the iteration function only deals with (and knows of) the members it needs to implement iteration.
Just note the calling the function is a little different now
void access_fn(struct link* link_p) {
struct command *cmd = (struct command*)link_p;
// do stuff
}
// ...
dll_iter(&cmd->link, access_fn);
Heck, now the function can even access more than one member at a time. How's that for flexibility?
It can be done. Time for stacking function pointers. We're getting really close to higher order functions now.
void dll_iter(t_command *lst, void *(*decoder)(t_command *entry), void (*f)(void *argpointer))
{
if (!lst || !decoder || !f)
return ;
while (lst)
{
f(decoder(lst));
lst = lst->next;
}
}
void *decoder_argc(t_command *entry) { return &entry->argc; }
void *decoder_argv(t_command *entry) { return &entry->argv; }
//...
Note that f always receives a pointer to the struct member.
Invocation looks like:
dll_iter(list, decoder_argc, f); // Process argc for all entries in list
dll_iter(list, decoder_argv, f); // ditto for argv

Retrieve data from a method of another class in C

I'm working on assignment for an operating systems class. We are given code to use to help us with our assignment, but I have little programming experience with C, and I can't figure out how to use it. What I'm trying to do is print the information at the head of the list. The list is a list of structs defined as
typedef struct
{
char name[NAME_MAX];
int lifetime;
} pcb_t;
int
List_head_info ( List_t *list, void **data )
{
int all_ok = 0;
*data = NULL;
if ((list != NULL) && (list->head != NULL)) {
*data = list->head->data;
all_ok = 1;
}
return all_ok;
}
I tried to display them with:
printf("test: %s", List_head_info(&processes, (void *)pcb)->name);
but I am given the error invalid type argument a->a when compiling.
When you call List_head_info(), you will get back two things:
A pointer (void *) to the head data, or NULL.
A status indicating whether the pointer is non-NULL.
If it returns successfully, you can convert (coerce, or cast) the void * to a pcb_t * and then use that to print the data.
How would I do that specifically?
Probably something a bit like this:
List_t list;
...code to initialize and maybe add things to the list...
void *head_data = 0;
if (List_head_info(&list, &head_data))
{
pcb_t *item = (pcb_t *)head_data;
printf("Lifetime: %.2d; Name: %s\n", item->lifetime, item->name);
}
Strictly, the initialization of head_data is superfluous; the code in List_head_info() always sets the value at least once (to NULL or 0) and sometimes twice (the second time to the data component of the head item on the list).
This is 'example code' with enough information in it to compile. I've 'reverse engineered' the list structures enough to make sense; the actual implementation will be different, of course. This compiles cleanly under fairly stringent GCC warning levels, with GCC 4.1.2 and 4.7.0 on Mac OS X 10.7.4. AFAICS, it avoids some complex issues related to 'strict aliasing' which you really don't want to have to worry about at this stage.
#include <stdio.h>
enum { NAME_MAX = 40 };
typedef struct Node Node;
struct Node
{
void *data;
Node *next;
};
typedef struct
{
Node *head;
Node *tail;
} List_t;
typedef struct
{
char name[NAME_MAX];
int lifetime;
} pcb_t;
extern int List_head_info(List_t *list, void **data);
extern void another_func(List_t processes);
void another_func(List_t list)
{
void *head_data = 0;
if (List_head_info(&list, &head_data))
{
pcb_t *item = (pcb_t *)head_data;
printf("Lifetime: %.2d; Name: %s\n", item->lifetime, item->name);
}
}
int
List_head_info ( List_t *list, void **data )
{
int all_ok = 0;
*data = NULL;
if ((list != NULL) && (list->head != NULL)) {
*data = list->head->data;
all_ok = 1;
}
return all_ok;
}

creating a queue of pointers in c

i have a dynamic number of pointers all having the same size. i need to store all the addresses of my pointers in some place like a link List in order to fetch them later on.
my question is what structs should i use. is the following correct:
struct Node{
int *k;
Node*Next;
}
struct LS{
Node*first,*last;
void push(Node*n);
Node* GetFirst();
Node* GetLast();
}
the LS is the linked list that stores Nodes. and a Node is a struct that holds the address of my pointer and a pointer to the next Node.
am i using int *k to store the address of my pointer correctly? should i continue with this implementation or is there any easier way to do this?
this sample code may help you start...
#include <stdio.h>
struct Node{
int *k;
Node *Next;
}* Temp;
struct LS
{
Node *first,*last;
void push(Node *MyNode)
{
MyNode->Next=NULL;
if(empty())
{
first=MyNode;
last=MyNode;
}
else
{
last->Next = MyNode;
last=MyNode;
}
}
Node* front()
{
return first;
}
void pop()
{
free(first->k);
first=first->Next;
}
bool empty()
{
if(first==NULL) return true;
return false;
}
};
int N=10;
int main()
{
LS Q;Q.first=NULL;
for(int i=0;i<3;i++)
{
Node *NewNode= (Node*)malloc(sizeof(Node));
NewNode->k = (int*)malloc(sizeof(int)*N);
for(int k=0;k<N;k++) NewNode->k[k]=i;
Q.push(NewNode);
}
while(!Q.empty())
{
Temp=Q.front();
for(int i=0;i<N;i++) printf("%d ",Temp->k[i]);
printf("\n");
Q.pop();
}
return 1;
}
Yes, your Node struct is correct.
As to whether there is an easier way it depends. If there is a maximum number of pointers that you will need then an array of pointers would be easier. If you can do it in C++ then an STL vector (can use it like an array, but underneath the hood it can grow dynamically as needed) is easier. If you have to do it in C and it has to be dynamic, though, then no, there is not an easier way.
WDM.H (microsoft header) has a bunch of linked list stuff to look at ( http://msdn.microsoft.com/en-us/library/ff547799(VS.85).aspx ) , I've cut and pasted from that, and added a very simple example.
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _MY_THING
{
LIST_ENTRY ListEntry;
ULONG randomdata1;
ULONG randomdata2;
ULONG randomdata3;
ULONG randomdata4;
} MY_THING, *PMY_THING;
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
VOID
InsertHeadList(
IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry
)
{
PLIST_ENTRY Flink;
Flink = ListHead->Flink;
Entry->Flink = Flink;
Entry->Blink = ListHead;
Flink->Blink = Entry;
ListHead->Flink = Entry;
}
VOID
InitializeListHead(
IN PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
PLIST_ENTRY
RemoveHeadList(
IN PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Flink;
PLIST_ENTRY Entry;
Entry = ListHead->Flink;
Flink = Entry->Flink;
ListHead->Flink = Flink;
Flink->Blink = ListHead;
return Entry;
}
void main()
{
LIST_ENTRY HeadOfMyList;
MY_THING Thing;
InitializeListHead(&Head);
// example of add thing to list.
InsertHeadList(&HeadOfMyList, &Thing.ListEntry);
// example of removing thing from the list
PLIST_ENTRY listEntry = RemoveHeadList(&HeadOfMyList);
PMY_THING pThing = (PMY_THING) CONTAINING_RECORD(listEntry, MY_THING, ListEntry);
}

C - Linked List and pointer problem

Hey,
I'm a beginner in C and tried to implement my own linked list implementation, that basically looks like this:
struct Element
{
void *value;
struct Element *next;
};
typedef struct
{
struct Element *first;
struct Element *last;
unsigned int size;
} LinkedList;
void LinkedList_init(LinkedList *this)
{
this->size = 0;
this->first = NULL;
this->last = NULL;
}
void LinkedList_add(LinkedList *this, void *value)
{
struct Element *node = malloc(sizeof(struct Element));
node->value = value;
node->next = NULL;
if (this->size == 0)
this->first = this->last = node;
else
{
this->last->next = node;
this->last = node;
}
this->size++;
}
So in short, I want a linked list that can hold arbitrary types - I heard, this is possible in C by using void pointers.
The problem now arises, when I want to use that implementation, for example with a structure as value:
typedef struct
{
int baz;
} Foo;
int main(void)
{
LinkedList list;
Foo bar;
bar.baz = 10;
LinkedList_init(&list);
LinkedList_add(&list, (void *) &bar);
/* try to get the element, that was just added ... */
Foo *firstElement = (Foo *)list.first;
/* ... and print its baz value */
printf("%d\n", firstElement->baz);
return 0;
}
The last printf call just prints values like -1077927056, which look like a memory address. So it's probably a problem with pointers. After searching the web the last few days for a similar issue on the web (I had no luck with that), I tried to throw my own logic away and tested various random *& combinations. Turns out, that was a dead end, too. :(
It's probably something simple for a more experienced C programmer, but I just can't find the answer. Please help :D
list.fist is a struct Element.
Try:
Foo *firstElement = (Foo *)(list.first->value);

What is the best way to write class template-like generic code in C?

I need to write AVL-tree with generic type in C. The best way I know is to use [ void* ] and to write some functions for creating, copying, assignment and destruction. Please, tell me some better way.
I will give you an example on how you can achieve generics functionality in C. The example is on a linked list, but I am sure you can adapt it on your AVL tree if necessary.
First of all you will need to define a structure for list element. A possible (most simple implementation):
struct list_element_s {
void *data;
struct list_element_s *next;
};
typedef struct list_element_s list_element;
Where 'data' will act as the "container" where you are going to keep your information, and 'next' is the reference to the direct linked element. (NOTE: Your binary tree element should include a reference to the right / left children elements).
After you create you element structure, you will need to create your list structure. A good practice is to have some members that are pointing to functions: destructor (needed to free the memory being hold by 'data'), and comparator (to be able to compare two of your list elements).
A list structure implementation could look like this:
struct list_s {
void (*destructor)(void *data);
int (*cmp)(const void *e1, const void *e2);
unsigned int size;
list_element *head;
list_element *tail;
};
typedef struct list_s list;
After you design your data structure, you should design your data structure interface. Let's say our list will have the following, most simple, interface:
nmlist *list_alloc(void (*destructor)(void *data));
int list_free(list *l);
int list_insert_next(list *l, list_element *element, const void *data);
void *list_remove_next(list *l, list_element *element);
Where:
list_alloc : will alocate memory for your list.
list_free : will free memory allocated for list, and all 'data' being held by list_element(s).
list_insert_next : will insert a new element next to 'element' . If 'element' is NULL, the insertion will be made at the head of the list.
list_remove_next : will remove & return (void*)'data' being held by 'element->next' . If 'element' is NULL, it will perform "list->head removal".
And now the functions implementation:
list *list_alloc(void (*destructor)(void *data))
{
list *l = NULL;
if ((l = calloc(1,sizeof(*l))) != NULL) {
l->size = 0;
l->destructor = destructor;
l->head = NULL;
l->tail = NULL;
}
return l;
}
int list_free(list *l)
{
void *data;
if(l == NULL || l->destructor == NULL){
return (-1);
}
while(l->size>0){
if((data = list_remove_next(l, NULL)) != NULL){
list->destructor(data);
}
}
free(l);
return (0);
}
int list_insert_next(list *l, list_element *element, const void *data)
{
list_element *new_e = NULL;
new_e = calloc(1, sizeof(*new_e));
if (l == NULL || new_e == NULL) {
return (-1);
}
new_e->data = (void*) data;
new_e->next = NULL;
if (element == NULL) {
if (l->size == 0) {
l->tail = new_e;
}
new_e->next = l->head;
l->head = new_e;
} else {
if (element->next == NULL) {
l->tail = new_e;
}
new_e->next = element->next;
element->next = new_e;
}
l->size++;
return (0);
}
void *list_remove_next(list *l, list_element *element)
{
void *data = NULL;
list_element *old_e = NULL;
if (l == NULL || l->size == 0) {
return NULL;
}
if (element == NULL) {
data = l->head->data;
old_e = l->head;
l->head = l->head->next;
if (l->size == 1) {
l->tail = NULL;
}
} else {
if (element->next == NULL) {
return NULL;
}
data = element->next->data;
old_e = element->next;
element->next = old_e->next;
if (element->next == NULL) {
l->tail = element;
}
}
free(old_e);
l->size--;
return data;
}
And now, how to use your simple generic linked list implementation. In the following example the list is acting like a stack:
#include <stdlib.h>
#include <stdio.h>
#include "nmlist.h"
void simple_free(void *data){
free(data);
}
int main(int argc, char *argv[]){
list *l = NULL;
int i, *j;
l = list_alloc(simple_free);
for(i = 0; i < 10; i++){
j = calloc(1, sizeof(*j));
if(j != NULL){
*j = i;
list_insert_next(l, NULL, (void*) j);
}
}
for(i = 0; i < 10; i++){
j = (int*) list_remove_next(l, NULL);
if(j != NULL){
printf("%d \n", *j);
}
}
list_free(l);
return (0);
}
Note that instead of "int *j" you can use a pointer that references more complex structures. If you do, don't forget to modify your 'list->destructor' function accordingly.
What Alex said. In c, void * is what there is.
Assuming you must work in C, though... Why do you need to provide the create/copy/assignment/destruction functions to the library? Which features of this library require the AVL-tree code to use those operations?
The major operations on a search tree are insert, delete and lookup, correct? You will need to provide a comparison function for all of those operations, but you should let the clients of this library handle all of the other operations. Simple is probably better in this case.
To do true, performant generics in C, you hack with the preprocessor. This approach has many of the same disadvantages of the C++ template approach; namely that all (most, anyway) code must live in header files, and debugging and testing are a pain. The advantages are also there; that you can get superior performance and let the compiler do all sorts of inlining to speed things up, minimize allocations by reducing indirection, and a modicum of type safety.
The definition looks like (let's imagine we have a hash set)
int my_int_set(int x);
#define HASH_SET_CONTAINED_TYPE int
#define HASH_SET_TYPE my_int_set
#define HASH_SET_FUNC hash_int
#include "hash_set.h"
And then to use it, you simply use the type you created above:
my_int_set x;
my_int_set_init(&x);
my_int_set_add(&x, 7);
if (my_int_set_check(&x, 7)) printf("It worked!\n");
...
// or, if you prefer
my_int_set *x = my_int_set_create();
Internally, this is implemented by a whole bunch of token pasting, etc., and (as noted above) is a huge pain to test.
So something like:
#ifndef HASH_SET_CONTAINED_TYPE
#error Must define HASH_SET_CONTAINED_TYPE
#endif
... /// more parameter checking
#define HASH_SET_ENTRY_TYPE HASH_SET_TYPE ## _entry
typedef struct HASH_SET_ENTRY_TYPE ## _tag {
HASH_SET_CONTAINED_TYPE key;
bool present;
} HASH_SET_ENTRY_TYPE;
typedef struct HASH_SET_TYPE ## _tag {
HASH_SET_TYPE ## _entry data[];
size_t elements;
} HASH_SET_TYPE;
void HASH_SET_TYPE ## _add(HASH_SET_CONTAINED_TYPE value) {
...
}
...
#undef HASH_SET_CONTAINED_TYPE
... // remaining uninitialization
You can even add options; like #define HASH_SET_VALUE_TYPE or #define HASH_SET_DEBUG.

Resources