===================================== Cleanup: Interface for Unique Strings [TOC] ===================================== Of course a unique string should not be mutable. Hence function _UStrAdd_ and ~UStrAdd_~ should of course return a const pointer. You should therefore update the header to: ---- CODE (file=session19/ustr/ustr.h) ----------------------------------------- #ifndef UTILS_USTR_H #define UTILS_USTR_H #include #include struct UStr { size_t len; char cstr[]; }; const struct UStr *UStrAdd_(const char *s, bool *added); const struct UStr *UStrAdd(const char *s); void UStrPrintPool(void); #endif // UTILS_USTR_H -------------------------------------------------------------------------------- Here the corresponding source file and the updated test program: ---- CODE (file=session19/ustr/ustr.c,fold) ------------------------------------ #include #include #include #include "ustr.h" struct Node { struct Node *next; struct UStr ustr; }; static struct Node *node; const struct UStr * UStrAdd_(const char *s, bool *added) { size_t len = strlen(s); if (added) { *added = true; } for (struct Node *n = node; n; n = n->next) { if (len == n->ustr.len && !strcmp(s, n->ustr.cstr)) { if (added) { *added = false; } return &n->ustr; } } struct Node *n = malloc(len + 1 + sizeof(size_t) + sizeof(struct Node *)); if (!n) { fprintf(stderr, "makeUStr: out of memory\n"); abort(); } n->next = node; n->ustr.len = len; strcpy(n->ustr.cstr, s); node = n; return &node->ustr; } const struct UStr * UStrAdd(const char *s) { return UStrAdd_(s, 0); } void UStrPrintPool(void) { for (const struct Node *n = node; n; n = n->next) { printf("%s\n", n->ustr.cstr); } } -------------------------------------------------------------------------------- ---- CODE (file=session19/ustr/xtest_ustr.c,fold) ------------------------------ #include #include "ustr.h" int main(void) { const struct UStr *kwIf = UStrAdd("if"); const struct UStr *kwWhile = UStrAdd("while"); char *line = 0; size_t capacity = 0; ssize_t len; while ((len = getline(&line, &capacity, stdin)) > 0) { line[len - 1] = 0; bool added = false; const struct UStr *ident = UStrAdd_(line, &added); if (ident == kwIf) { printf("keyword 'if'\n"); } else if (ident == kwWhile) { printf("keyword 'while'\n"); } else { printf("identifier '%s'\n", ident->cstr); if (added) { printf("this is new\n"); } } } printf("Pool of UStr:\n"); UStrPrintPool(); } --------------------------------------------------------------------------------