DevHeads.net

dumb apr_pool question

Hi everyone,

Am I correct to assume that a pool cannot be forcibly (prematurely)
freed? I was trying to understand apr_hash and wanted to free the memory
allocated for the keys and then try a apr_hash_get. You know, put it
through it's paces ;)

I read about apr_pool_clear:
"This does not actually free the memory, it just allows the pool to
re-use this memory for the next allocation."
but about apr_pool_destroy:
"This will actually free the memory"

However, when I run this simple program through valgrind, there are no
memory errors.

I suppose that the pool is keeping track of all it's allocations and if
something is still referenced, it will not free it.

I also suppose that "This will actually free the memory" is ambiguous:
<a href="https://apr.apache.org/docs/apr/1.6/group__apr__pools.html#ga54759954d2cba7cb649ab5680a33f9e3" title="https://apr.apache.org/docs/apr/1.6/group__apr__pools.html#ga54759954d2cba7cb649ab5680a33f9e3">https://apr.apache.org/docs/apr/1.6/group__apr__pools.html#ga54759954d2c...</a>

<a href="https://apr.apache.org/docs/apr/trunk/group__apr__pools.html#ga54759954d2cba7cb649ab5680a33f9e3" title="https://apr.apache.org/docs/apr/trunk/group__apr__pools.html#ga54759954d2cba7cb649ab5680a33f9e3">https://apr.apache.org/docs/apr/trunk/group__apr__pools.html#ga54759954d...</a>

Kind regards,

Simon

#include <stdio.h>
#include <linux/limits.h>
#include <apr-1.0/apr_pools.h>

char * test_destroy(void);

char * test_destroy(void)
{
apr_pool_t * Crash = NULL;
apr_pool_create(&Crash, NULL);
char * String = apr_pcalloc(Crash, 4);
strcpy(String, "txt");
apr_pool_destroy(Crash);
return String;
}

int main(int ArgCount, char * Arg[])
{
apr_initialize();
char * String = test_destroy();
printf("String: %s\n", String);
apr_terminate();
return 0;
}

Comments

Re: dumb apr_pool question

By Eric Covener at 01/11/2018 - 09:05

On Thu, Jan 11, 2018 at 3:55 AM, Simon Walter < ... at gikaku dot com> wrote:
apr_pool_destroy should do this.

No the only tracking is done by whoever manages the lifecycle of the
pool itself -- no magic.

apr_pool_destroy will call free() or munmap or any underlying
allocation on the way out, returning it to the OS.

Re: dumb apr_pool question

By Yann Ylavic at 01/11/2018 - 10:12

On Thu, Jan 11, 2018 at 3:05 PM, Eric Covener < ... at gmail dot com> wrote:
Actually the memory is returned to the (apr_)allocator, which itself
may cache for further reuse.
One can use apr_allocator_max_free_set() to limit the number of pages
cached (no limit by default), e.g. something like the following code
based on Simon's (not even compile tested...):

int main(int ArgCount, char * Arg[])
{
char * String;
apr_pool_t * Pool = NULL;
apr_allocator_t * Alloc = NULL;
apr_initialize();

/* New allocator (not the default/unlimited one) */
apr_allocator_create(&Alloc);
/* Cache one page only (may be 4K pages, not system's),
* zero is unlimited, so the cache is always 1 page min... */
apr_allocator_max_free_set(Alloc, 1/*page*/);
/* Use this allocator for the pool */
apr_pool_create_ex(&Pool, NULL, NULL, Alloc);
/* Destroy Alloc when destroying Pool */
apr_allocator_owner_set(Alloc, Pool);

/* Won't crash (possibly), don't do that for real... */
String = apr_pstrdup(Pool, "small alloc");
apr_pool_clear(Pool);
printf("String: %s\n", String);

/* Should crash */
(void)apr_palloc(Pool, 4100);
(void)apr_palloc(Pool, 4100);
(void)apr_palloc(Pool, 4100);
String = apr_pstrdup(Pool, "small alloc");
apr_pool_clear(Pool);
printf("String: %s\n", String);

/* Should also crash */
String = apr_pstrdup(Pool, "small alloc");
apr_pool_destroy(Pool); /* + Alloc */
printf("String: %s\n", String);

apr_terminate();
return 0;
}