On Mon, Jun 4, 2012 at 12:00 PM, Alexander Broekhuis wrote: > Hi > > >> I'm not a C - expert, but I think the only viable solution is to >> accurately document the lifetime and ownership of pointers. >> > > Well I think this is not a C specific problem, the same applies to C++ I > guess. Someone has to free allocated memory. > >> >> For memory owned by the framework, any memory management technique which >> guarantees the stated lifetime will do (e.g. APR memory pools). >> > > Since this is "internal" to the framework this can be anything the > framework implementation uses. For Celix this is indeed APR. > > Memory which is to be owned by the caller (user) could probably be >> allocated and deleted by using special functions (hooks) provided by each >> bundle which use implementation specific routines for memory management. >> Otherwise we just state that the returned memory belongs to the caller. >> > > This is the more interesting part of the problem. > > How would such hooks look like, and doesn't this making bundles awkward? > > A generic header for this could look like this: > memory_hooks.h: >  int mem_alloc(void *handle, size_t size, void **block); >  int mem_calloc(void *handle, size_t num, size_t size, void **block); >  int mem_realloc(void *handle, void *block, size_t size, void **newblock); >  int mem_free(void *handle, void *block); > > These function are basically the "normal" C memory functions, does C++ have > different/additional ones? > I've added a *handle to all of them to be able to pass some "instance" to > it. For example, APR would need a memory pool, which can be a member of the > instance type/struct. > > How does the framework get the handle? One additional method could work: > int mem_createHandle(void **handle); > > For APR: > mem_alloc -> use apr_palloc(handle->pool, size) > mem_calloc -> use apr_pcalloc(handle->pool, size) > mem_realloc -> no alternative in APR, implement a solution like [1] > mem_free -> not implemented, the user has to clear the pool at some time > > Looking at it like this, I just realize this solution has a huge drawback > when used in combination with APR. For different calls different pools are > needed. Using this model, there is only one pool which is used for every > allocation. Basically this means the user is not in control of the lifetime > of memory. > The only solution I can think of is to have the user supply the pool on > which the memory has to be allocated, but we don't want this on our API. > > A possibility would be to supply the handle (instead of the pool) which is > used by the memory hooks. For example: > > int bundle_getEntry(bundle, handle, char *name, char **entry) > > Instead of letting the framework use handle, handle is simply passed on the > the memory hooks and used in a way the caller wants. This also eliminates > the need for the createHandle function in the header file. The user can > create one when needed. In case of APR, this handle probably can directly > be the pool. > > I hope this still makes sense... It does :), but IMO supplying handles - even on framework level - is not a good idea. It will add too much complexity for something where most C programmers just expect to use of malloc and free. Personally I am in favor for using memory pools, but for a generic API I think we should keep close to "pure" C and in this case use malloc and let the users call free. > > [1]: http://marc.info/?l=apr-dev&m=109065999530290&w=2 > > -- > Met vriendelijke groet, > > Alexander Broekhuis