- Notifications
You must be signed in to change notification settings - Fork145
Smart pointers for the (GNU) C programming language
License
Snaipe/libcsptr
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This project is an attempt to bring smart pointer constructsto the (GNU) C programming language.
unique_ptr
,shared_ptr
macros, andsmart
type attribute- Destructor support for cleanup
- Custom variable metadata on allocation
- 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)
Mac OS X:
brew install snaipe/soft/libcsptr
AUR:
yaourt -S libcsptr
Ubuntu:
$ sudo add-apt-repository ppa:snaipewastaken/ppa$ sudo apt-get update$ sudo apt-get install libcsptr-dev
To compile the library, GCC 4.6+ is needed.
- Clone this repository
- run
mkdir build && cd $_ && cmake -DCMAKE_INSTALL_PREFIX=$HOME .. && make && make install
from the project root for a local install, or runmkdir build && cd $_ && cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make && sudo make install
for a global install.
- Simple unique_ptr:simple1.c:Shell session:
#include<stdio.h>#include<csptr/smart_ptr.h>intmain(void) {// some_int is an unique_ptr to an int with a value of 1.smartint*some_int=unique_ptr(int,1);printf("%p = %d\n",some_int,*some_int);// some_int is destroyed herereturn0;}
$ gcc -std=c99 -o simple1 simple1.c -lcsptr$ valgrind ./simple1==3407== Memcheck, a memory error detector==3407== Copyright (C) 2002-2013, and GNU GPL\'d, by Julian Seward et al.==3407== Using Valgrind-3.10.0 and LibVEX; rerun with -hfor copyright info==3407== Command: ./test1==3407==0x53db068 = 1==3407====3407== HEAP SUMMARY:==3407==in use at exit: 0 bytesin 0 blocks==3407== total heap usage: 1 allocs, 1 frees, 48 bytes allocated==3407====3407== All heap blocks were freed -- no leaks are possible==3407====3407== For counts of detected and suppressed errors, rerun with: -v==3407== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
- Simple unique_ptr with destructor:
#include<unistd.h>#include<fcntl.h>#include<csptr/smart_ptr.h>structlog_file {intfd;// ...};voidcleanup_log_file(void*ptr,void*meta) { (void)meta;close(((structlog_file*)ptr)->fd);}intmain(void) {smartstructlog_file*log=unique_ptr(structlog_file, { .fd=open("/dev/null",O_WRONLY |O_APPEND),// ... },cleanup_log_file);write(log->fd,"Hello",5);// cleanup_log_file is called, then log is freedreturn0;}
- Allocating a smart array and printing its contents before destruction:
#include<stdio.h>#include<csptr/smart_ptr.h>#include<csptr/array.h>voidprint_int(void*ptr,void*meta) { (void)meta;// ptr points to the current element// meta points to the array metadata (global to the array), if any.printf("%d\n",*(int*)ptr);}intmain(void) {// Destructors for array types are run on every element of the// array before destruction.smartint*ints=unique_ptr(int[5], {5,4,3,2,1},print_int);// ints == {5, 4, 3, 2, 1}// Smart arrays are length-awarefor (size_ti=0;i<array_length(ints);++i) {ints[i]=i+1; }// ints == {1, 2, 3, 4, 5}return0;}
Using a different memory allocator (although most will replace malloc/free):
#include<csptr/smart_ptr.h>void*some_allocator(size_t);voidsome_deallocator(void*);intmain(void) {smalloc_allocator= (s_allocator) {some_allocator,some_deallocator};// ...return0;}
Automatic cleanup on error cases:
#include<unistd.h>#include<fcntl.h>#include<csptr/smart_ptr.h>structlog_file {intfd;// ...};staticvoidclose_log(void*ptr,void*meta) { (void)meta;structlog_file*log=ptr;if (log->fd!=-1)close(log->fd);}structlog_file*open_log(constchar*path) {smartstructlog_file*log=shared_ptr(structlog_file, {0},close_log);if (!log)// failure to allocatereturnNULL;// nothing happens, destructor is not calledlog->fd=open(path,O_WRONLY |O_APPEND |O_CREAT,0644);if (log->fd==-1)// failure to openreturnNULL;// log gets destroyed, file descriptor is not closed since fd == -1.returnsref(log);// a new reference on log is returned, it does not get destoyed}intmain(void) {smartstructlog_file*log=open_log("/dev/null");// ...return0;// file descriptor is closed, log is freed}
Using named parameters:
#include<csptr/smart_ptr.h>voidnothing(void*ptr,void*meta) {}intmain(void) {struct {inta; }m= {1 };smartint*i=unique_ptr(int, .dtor=nothing, .value=42, .meta= {&m,sizeof (m) } );return0;}
Q. Why didn't you use C++ you moron ?
A. Because when I first started this, I was working on a C project.Also, because it's fun.
Q. Can I use this on a serious project ?
A. Yes, but as this project has not been widely used, there might besome bugs. Beware!
Q. How did you make this ?
A. Here's alink to my blog post on the matter.
About
Smart pointers for the (GNU) C programming language
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors5
Uh oh!
There was an error while loading.Please reload this page.