Question

In my Apache module, which is built in C++, I uses strings, vectors, and the related when attempting to provide functionality to my module.

My concern is that I am not using the Apache memory pool and that the program is going to segfault along the way, but at the same time I having difficulty with certain task such as this:

static void parseSTR(char *input, const char *sep, int &count, apr_table_t *&values, apr_pool_t *mp)
{
    char *part, *next;

    if (isStrNull(input)) 
        return;

    count = 1;

    part = apr_strtok(input, sep, &next);

    while (part) {
        apr_table_set(values, apr_itoa(mp, count), part);

        part = apr_strtok(NULL, sep, &next);

        count++;
    }
}

which I am using a delimited string parser to parse URLs and domain names. Surely there is a more efficient way to provide this functionality. I am using the apr_table structure to contain each part, I know I could use an apr_array_header, but....

So I would like to know:

  1. Could I use Boost to provide the missing functionality SAFELY?
  2. Will I run into memory clashes because I am not using the pool memory?
  3. For string, vector, and etc that free their own memory, is this a problem laying in wait?

I did search for this issue, but the other issues do not seem to be the same.

Was it helpful?

Solution

Using Boost should be safe, it depends on the specific parts you're using though to make any definite calls on its safety.

As for memory management, you could write your own implementation of std::allocator that uses Apache/APR's memory allocation. You can then pass this allocator as a template argument to the STL containers you're using (usually the second template argument).

As for Boost's smart-pointers (if you're using them), they can (on construction) be given a function-pointer as parameter that implements memory-deallocation (as a replacement for delete).

E.g. an allocator like this could do the trick for you:

#include <stdexcept>

template <typename T>
class apr_allocator
{
    public:
        typedef size_t    size_type;
        typedef ptrdiff_t difference_type;
        typedef T*        pointer;
        typedef const T*  const_pointer;
        typedef T&        reference;
        typedef const T&  const_reference;
        typedef T         value_type;

        template<typename U>
        struct rebind
        { typedef apr_allocator<U> other; };

        pointer allocate(size_type n, const void* = 0)
        {
            pointer new_mem = apr_do_whatever_is_necessary_to_allocate(n * sizeof(value_type));
            if (!new_mem)
                throw std::bad_alloc();
            return new_mem;
        }

        void deallocate(pointer p, size_type n)
        {
            apr_release_memory(p, n);
        }

        pointer address(reference r) const
        {
            return &r;
        }

        const_pointer address(const_reference r) const
        {
            return &r;
        }

        size_type max_size() const
        {
            // Largest amount of elements T that can meaningfully be allocated
            return 1337;
        }

        void construct(pointer p, const_reference val)
        {
            new ((void *)p) value_type(val);
        }

        void destroy(pointer p)
        {
            p->~T();
        }
};

template <typename T>
inline bool operator==(const apr_allocator<T>& a, const new_allocator<T>& b)
{
    if (&a == &b)
        return true;
    if (/* a can deallocate elements created with b and vice-versa */)
        return true;
    return false;
}

template <typename T>
inline bool operator!=(const apr_allocator<T>& a, const apr_allocator<T>& b)
{
    return !(a == b);
}

Also note that if your allocator requires internal state (e.g. a reference to a specific memory-pool) you must ensure that the allocator is copy-constructable. Also it must be default constructible (though you can pass a pre-constructed instance as parameter to STL containers' constructors).

OTHER TIPS

We are using C++ and Boost heavily in Apache on Windows and we do not see any problems related to our use of new or similar C++isms.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top