3

C ++で構築されているApacheモジュールでは、モジュールに機能を提供しようとするときに、文字列、ベクトル、および関連するものを使用します。

私の懸念は、Apacheメモリプールを使用しておらず、プログラムが途中でセグメンテーション違反を起こすことですが、同時に、次のような特定のタスクに問題があります。

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

これは、URLとドメイン名を解析するために区切り文字列パーサーを使用しています。確かに、この機能を提供するためのより効率的な方法があります。私はapr_table構造体を使用して各部分を格納していますが、apr_array_headerを使用できることはわかっていますが...。

だから私は知りたいです:

  1. Boostを使用して、不足している機能を安全に提供できますか?
  2. プールメモリを使用していないため、メモリの衝突が発生しますか?
  3. 自分のメモリを解放する文字列やベクトルなどの場合、これは待機中の問題ですか?

この問題を検索しましたが、他の問題は同じではないようです。

4

2 に答える 2

2

Boostの使用は安全である必要があります。それは、安全性について明確な呼びかけをするために使用している特定の部品によって異なります。

メモリ管理に関しては、Apache/APRのメモリ割り当てを使用するstd::allocatorの独自の実装を作成できます。次に、このアロケータをテンプレート引数として、使用しているSTLコンテナ(通常は2番目のテンプレート引数)に渡すことができます。

Boostのスマートポインタ(使用している場合)については、(構築時に)メモリの割り当て解除を実装するパラメータとして(の代わりに)関数ポインタを指定できますdelete

たとえば、このようなアロケータはあなたのためにトリックを行うことができます:

#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);
}

また、アロケータが内部状態(特定のメモリプールへの参照など)を必要とする場合は、アロケータがコピー構築可能であることを確認する必要があることにも注意してください。また、デフォルトで構築可能である必要があります(ただし、事前に構築されたインスタンスをパラメーターとしてSTLコンテナーのコンストラクターに渡すことができます)。

于 2012-07-22T15:03:14.937 に答える
0

newWindows上のApacheでC++とBoostを多用しており、 C++や同様のC++ismの使用に関連する問題は見られません。

于 2012-07-22T14:15:35.643 に答える