Skip to content

Instantly share code, notes, and snippets.

@alphaKAI
Last active June 10, 2016 13:53
Show Gist options
  • Save alphaKAI/93fd9ab092b27fc6143975c959017bcf to your computer and use it in GitHub Desktop.
Save alphaKAI/93fd9ab092b27fc6143975c959017bcf to your computer and use it in GitHub Desktop.
データとリストを分離し、任意の型で簡単に単方向リストを実装できるようにするサンプル(Linuxカーネルでの実装を参考にしました。)
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
void *xmalloc(size_t size) {
void *ret;
ret = malloc(size);
if (ret == NULL) {
exit(EXIT_FAILURE);
}
return ret;
}
typedef struct _node {
struct _node* next;
} Node;
void free_all_node(Node* node) {
if (node != NULL) {
if (node->next != NULL) {
free_all_node(node->next);
}
free(node);
}
}
void free_nodes(Node* node) {
if (node->next != NULL) {
free_nodes(node->next);
}
free(node);
}
Node* get_last_node(Node* node) {
Node* thisNode;
for (thisNode = node; thisNode->next != NULL; thisNode = thisNode->next) ;
return thisNode;
}
bool is_singlelist_empty(Node* node) {
return node == NULL;
}
void add_node(Node* parent, Node* child) {
child->next = NULL;
if (is_singlelist_empty(parent)) {
parent = child;
} else {
Node* lastNode = get_last_node(parent);
parent->next = child;
}
}
struct IntList {
Node* node;
int value;
};
void add_int_value(struct IntList* parent, int* value) {
struct IntList* child = (struct IntList*)xmalloc(sizeof(struct IntList));
child->node = (Node*)xmalloc(sizeof(Node));
child->value = *value;
add_node(parent->node, child->node);
}
struct IntList* get_int_value(int* value) {
struct IntList* il = container_of(value, struct IntList, value);
return il;
}
void testIntList() {
struct IntList parent = {};
parent.node = (Node*)xmalloc(sizeof(Node));
parent.node->next = NULL;
for (int i = 0; i < 10; i++) {
add_int_value(&parent, &i);
}
for (int i = 0; i < 10; i++) {
struct IntList* il = get_int_value(&i);
printf("NUM:%d\n", il->value);
}
free_all_node(parent.node);
}
struct CharList {
Node* node;
char* value;
};
void add_char_value(struct CharList* parent, char* value) {
struct CharList* child = (struct CharList*)xmalloc(sizeof(struct CharList));
child->node = (Node*)xmalloc(sizeof(Node));
child->value = value;
add_node(parent->node, child->node);
}
struct CharList* get_char_value(char* value) {
struct CharList* cl = container_of(&value, struct CharList, value);
return cl;
}
void testCharList() {
struct CharList parent;
parent.node = (Node*)xmalloc(sizeof(Node));
parent.node->next = NULL;
char* chars[] = {
"value1",
"value2",
"value3",
"value4"
};
for (int i = 0; i < 4; i++) {
add_char_value(&parent, chars[i]);
}
for (int i = 0; i < 4; i++) {
struct CharList* cl = get_char_value(chars[i]);
printf("CHAR:%s\n", cl->value);
}
free_all_node(parent.node);
}
int main() {
testIntList();
testCharList();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment