{"id":32986488,"url":"https://github.com/Snaipe/libcsptr","last_synced_at":"2025-11-13T14:01:26.058Z","repository":{"id":25582881,"uuid":"29017019","full_name":"Snaipe/libcsptr","owner":"Snaipe","description":"Smart pointers for the (GNU) C programming language","archived":false,"fork":false,"pushed_at":"2022-11-02T10:43:12.000Z","size":140,"stargazers_count":1665,"open_issues_count":12,"forks_count":146,"subscribers_count":60,"default_branch":"master","last_synced_at":"2025-05-23T03:01:57.426Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://snai.pe/c/c-smart-pointers/","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Snaipe.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-09T13:16:42.000Z","updated_at":"2025-05-22T03:49:35.000Z","dependencies_parsed_at":"2023-01-14T02:59:27.824Z","dependency_job_id":null,"html_url":"https://github.com/Snaipe/libcsptr","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/Snaipe/libcsptr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snaipe%2Flibcsptr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snaipe%2Flibcsptr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snaipe%2Flibcsptr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snaipe%2Flibcsptr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Snaipe","download_url":"https://codeload.github.com/Snaipe/libcsptr/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snaipe%2Flibcsptr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284227494,"owners_count":26968592,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-13T02:00:06.582Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-11-13T08:00:38.177Z","updated_at":"2025-11-13T14:01:26.053Z","avatar_url":"https://github.com/Snaipe.png","language":"CMake","readme":"C Smart Pointers\n================\n\n[![Build Status](https://travis-ci.org/Snaipe/libcsptr.svg?branch=master)](https://travis-ci.org/Snaipe/libcsptr) \n[![Coverage Status](https://coveralls.io/repos/Snaipe/libcsptr/badge.svg?branch=master)](https://coveralls.io/r/Snaipe/libcsptr?branch=master) \n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/Snaipe/libcsptr/blob/master/LICENSE) \n[![Version](https://img.shields.io/github/tag/Snaipe/libcsptr.svg?label=version\u0026style=flat)](https://github.com/Snaipe/libcsptr/releases)\n\n## What this is\n\nThis project is an attempt to bring smart pointer constructs\nto the (GNU) C programming language.\n\n### Features\n\n* `unique_ptr`, `shared_ptr` macros, and `smart` type attribute\n* Destructor support for cleanup\n* Custom variable metadata on allocation\n* Cross-platform: tested under linux 3.18.6-1, Mac OS X Yosemite 10.10, and Windows 7 (with MinGW and the Cygwin port of GCC)\n\n## Installing\n\n### With a package manager\n\n* Mac OS X: `brew install snaipe/soft/libcsptr`\n* [AUR](https://aur.archlinux.org/packages/libcsptr-git/): `yaourt -S libcsptr`\n* Ubuntu:\n\n    ```bash\n    $ sudo add-apt-repository ppa:snaipewastaken/ppa\n    $ sudo apt-get update\n    $ sudo apt-get install libcsptr-dev\n    ```\n\n### Building from source\n#### Prerequisites\n\nTo compile the library, GCC 4.6+ is needed.\n\n#### Installation\n\n1. Clone this repository\n2. run `mkdir build \u0026\u0026 cd $_ \u0026\u0026 cmake -DCMAKE_INSTALL_PREFIX=$HOME .. \u0026\u0026 make \u0026\u0026 make install`  \n   from the project root for a local install, or run  \n   `mkdir build \u0026\u0026 cd $_ \u0026\u0026 cmake -DCMAKE_INSTALL_PREFIX=/usr .. \u0026\u0026 make \u0026\u0026 sudo make install` for a global install.\n\n## Examples\n\n* Simple unique\\_ptr:\n    simple1.c:\n    ```c\n    #include \u003cstdio.h\u003e\n    #include \u003ccsptr/smart_ptr.h\u003e\n\n    int main(void) {\n        // some_int is an unique_ptr to an int with a value of 1.\n        smart int *some_int = unique_ptr(int, 1);\n\n        printf(\"%p = %d\\n\", some_int, *some_int);\n\n        // some_int is destroyed here\n        return 0;\n    }\n    ```\n    Shell session:\n    ```bash\n    $ gcc -std=c99 -o simple1 simple1.c -lcsptr\n    $ valgrind ./simple1\n    ==3407== Memcheck, a memory error detector\n    ==3407== Copyright (C) 2002-2013, and GNU GPL\\'d, by Julian Seward et al.\n    ==3407== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info\n    ==3407== Command: ./test1\n    ==3407==\n    0x53db068 = 1\n    ==3407==\n    ==3407== HEAP SUMMARY:\n    ==3407==     in use at exit: 0 bytes in 0 blocks\n    ==3407==   total heap usage: 1 allocs, 1 frees, 48 bytes allocated\n    ==3407==\n    ==3407== All heap blocks were freed -- no leaks are possible\n    ==3407==\n    ==3407== For counts of detected and suppressed errors, rerun with: -v\n    ==3407== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)\n    ```\n* Simple unique\\_ptr with destructor:\n    ```c\n    #include \u003cunistd.h\u003e\n    #include \u003cfcntl.h\u003e\n    #include \u003ccsptr/smart_ptr.h\u003e\n\n    struct log_file {\n        int fd;\n        // ...\n    };\n\n    void cleanup_log_file(void *ptr, void *meta) {\n        (void) meta;\n        close(((struct log_file *) ptr)-\u003efd);\n    }\n\n    int main(void) {\n        smart struct log_file *log = unique_ptr(struct log_file, {\n                .fd = open(\"/dev/null\", O_WRONLY | O_APPEND),\n                // ...\n            }, cleanup_log_file);\n\n        write(log-\u003efd, \"Hello\", 5);\n\n        // cleanup_log_file is called, then log is freed\n        return 0;\n    }\n    ```\n* Allocating a smart array and printing its contents before destruction:\n    ```c\n    #include \u003cstdio.h\u003e\n    #include \u003ccsptr/smart_ptr.h\u003e\n    #include \u003ccsptr/array.h\u003e\n\n    void print_int(void *ptr, void *meta) {\n        (void) meta;\n        // ptr points to the current element\n        // meta points to the array metadata (global to the array), if any.\n        printf(\"%d\\n\", *(int*) ptr);\n    }\n\n    int main(void) {\n        // Destructors for array types are run on every element of the\n        // array before destruction.\n        smart int *ints = unique_ptr(int[5], {5, 4, 3, 2, 1}, print_int);\n        // ints == {5, 4, 3, 2, 1}\n\n        // Smart arrays are length-aware\n        for (size_t i = 0; i \u003c array_length(ints); ++i) {\n            ints[i] = i + 1;\n        }\n        // ints == {1, 2, 3, 4, 5}\n\n        return 0;\n    }\n    ```\n\n## More examples\n\n* Using a different memory allocator (although most will replace malloc/free):\n    ```c\n    #include \u003ccsptr/smart_ptr.h\u003e\n\n    void *some_allocator(size_t);\n    void some_deallocator(void *);\n\n    int main(void) {\n        smalloc_allocator = (s_allocator) {some_allocator, some_deallocator};\n        // ...\n        return 0;\n    }\n    ```\n\n* Automatic cleanup on error cases:\n    ```c\n    #include \u003cunistd.h\u003e\n    #include \u003cfcntl.h\u003e\n    #include \u003ccsptr/smart_ptr.h\u003e\n\n    struct log_file {\n        int fd;\n        // ...\n    };\n\n    static void close_log(void *ptr, void *meta) {\n        (void) meta;\n        struct log_file *log = ptr;\n        if (log-\u003efd != -1)\n            close(log-\u003efd);\n    }\n\n    struct log_file *open_log(const char *path) {\n        smart struct log_file *log = shared_ptr(struct log_file, {0}, close_log);\n        if (!log) // failure to allocate\n            return NULL; // nothing happens, destructor is not called\n\n        log-\u003efd = open(path, O_WRONLY | O_APPEND | O_CREAT, 0644);\n        if (log-\u003efd == -1) // failure to open\n            return NULL; // log gets destroyed, file descriptor is not closed since fd == -1.\n\n        return sref(log); // a new reference on log is returned, it does not get destoyed\n    }\n\n    int main(void) {\n        smart struct log_file *log = open_log(\"/dev/null\");\n        // ...\n        return 0; // file descriptor is closed, log is freed\n    }\n    ```\n* Using named parameters:\n    ```c\n    #include \u003ccsptr/smart_ptr.h\u003e\n\n    void nothing(void *ptr, void *meta) {}\n\n    int main(void) {\n        struct { int a; } m = { 1 };\n\n        smart int *i = unique_ptr(int,\n                .dtor = nothing,\n                .value = 42,\n                .meta = { \u0026m, sizeof (m) }\n            );\n\n        return 0;\n    }\n    ```\n\n## FAQ\n\n**Q. Why didn't you use C++ you moron ?**  \nA. Because when I first started this, I was working on a C project.\n   Also, because it's fun.\n\n**Q. Can I use this on a serious project ?**  \nA. Yes, but as this project has not been widely used, there might be\n   some bugs. Beware!\n\n**Q. How did you make this ?**  \nA. Here's a [link to my blog post](http://snaipe.me/c/c-smart-pointers/) on the matter.\n","funding_links":[],"categories":["Memory Allocation","Memory Management","内存管理","内存分配","Miscellaneous"],"sub_categories":["Advanced books","高级书籍","数学"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSnaipe%2Flibcsptr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSnaipe%2Flibcsptr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSnaipe%2Flibcsptr/lists"}