Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Smart pointers for the (GNU) C programming language

License

NotificationsYou must be signed in to change notification settings

Snaipe/libcsptr

Repository files navigation

Build StatusCoverage StatusLicenseVersion

What this is

This project is an attempt to bring smart pointer constructsto the (GNU) C programming language.

Features

  • 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)

Installing

With a package manager

  • 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

Building from source

Prerequisites

To compile the library, GCC 4.6+ is needed.

Installation

  1. Clone this repository
  2. runmkdir build && cd $_ && cmake -DCMAKE_INSTALL_PREFIX=$HOME .. && make && make install
    from the project root for a local install, or run
    mkdir build && cd $_ && cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make && sudo make install for a global install.

Examples

  • Simple unique_ptr:simple1.c:
    #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;}
    Shell session:
    $ 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;}

More examples

  • 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;}

FAQ

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.


[8]ページ先頭

©2009-2025 Movatter.jp