2

C の realloc 関数に問題があります。次のコードを渡します。

typedef struct _Pool Pool;
typedef struct _Item Item;

struct _Pool {
    Item ** items;
    unsigned int itemsCount;
    unsigned int poolSize;
    unsigned int poolStep;
};

struct _Item {
    char * file; 
    unsigned int lenOfFilePath;
    unsigned int x;
};

void Pool_insert(Pool ** pool, Item * item)
{       
    if ((*pool)->itemsCount + 1 == (*pool)->poolSize)
    {
        (*pool)->items = realloc((*pool)->items, sizeof(Item *)*((*pool)->poolSize + (*pool)->poolStep));;
        if (!(*pool)->items) return;
        (*pool)->poolSize += (*pool)->poolStep;
    }

    (*pool)->items[(*pool)->itemsCount++] = item;
}

最初の割り当てコードを送信していませんが、そこで使用しているアイテムの数を増やすと、すべて正常に機能します。realloc を呼び出すと、次のようなエラーが発生します。

malloc: *** オブジェクト 0x19dba8 のエラー: 再割り当てされるポインターが割り当てられませんでした

私の問題を解決するのを手伝ってくれませんか?


プールの作成方法は次のとおりです。

void Pool_create(Pool ** pool, unsigned int poolSize)
{   
    unsigned int poolMemSize = sizeof(Pool) + sizeof(Item *)*poolSize;
    *pool = malloc(poolMemSize);
    if (!*pool) return;
    memset(*pool,0,poolMemSize);

    (*pool)->itemsCount = 0;
    (*pool)->poolSize = poolSize;
    (*pool)->poolStep = POOL_STEP;

    (*pool)->items = (Item **)((char*)(*pool) + sizeof(Pool));
    if(!(*pool)->items) return;
    memset((*pool)->items, 0, sizeof(Item *) * poolSize);
}

私が言ったように、たとえば1000個のアイテムを挿入し、create関数によってメモリを割り当てたい場合、100個の要素の開始プールサイズを宣言してからアイテムを再割り当てしたい場合、エラーが発生します。

このような迅速な回答をありがとうございました。

4

4 に答える 4

1

しかし、(*pool)->items割り当てられることはありませんでした!割り当て(*pool)たのは、メモリのスライス全体です。この場合、2つのmallocを使用する必要があります。1つは制御構造(プール)用で、もう1つはitems*配列用です。

明確化:割り当てられたメモリの一部を再割り当てすることはできません-mallocされたチャンク全体のみ。また、適切に記述されたコードで元のポインタを置き換える前に、最初にreallocの結果をテストする必要があることに注意してください。そうしないと、reallocが失敗すると、以前に割り当てられたメモリブロックが失われます。

于 2009-07-02T18:16:31.023 に答える
0

プールの作成方法は次のとおりです。

void Pool_create(Pool ** pool, unsigned int poolSize)
{   
    unsigned int poolMemSize = sizeof(Pool) + sizeof(Item *)*poolSize;
    *pool = malloc(poolMemSize);
    if (!*pool) return;
    memset(*pool,0,poolMemSize);

    (*pool)->itemsCount = 0;
    (*pool)->poolSize = poolSize;
    (*pool)->poolStep = POOL_STEP;

    (*pool)->items = (Item **)((char*)(*pool) + sizeof(Pool));
    if(!(*pool)->items) return;
    memset((*pool)->items, 0, sizeof(Item *) * poolSize);
}

私が言ったように、たとえば1000アイテムを挿入し、create関数でメモリを割り当てたい場合、100要素の開始プールサイズを宣言してからアイテムを再割り当てすると、エラーが発生します。

こんなに早く答えてくれてありがとう。

于 2009-07-02T18:12:33.760 に答える
0
struct _Pool {
    Item ** items;
    unsigned int itemsCount;
    unsigned int poolSize;
    unsigned int poolStep;
};

malloc: *** オブジェクト 0x19dba8 のエラー: 再割り当てされるポインターが割り当てられませんでした

malloc を使用してアイテムにメモリを割り当てていますか? そのメッセージは、あなたがそうではないことを伝えているようです。realloc は、malloc のような関数で割り当てられたメモリに使用する必要があります。

(*pool)->items = realloc((*pool)->items, sizeof(Item *)*((*pool)->poolSize + (*pool)->poolStep));;

さらにヘルプが必要な場合は、アイテムを初期化する方法を教えてください。

于 2009-07-02T18:01:18.363 に答える
0

構造内の *items を初期化するのを忘れて、ワイルド ポインターを追跡している可能性があります。

于 2009-07-02T18:03:23.663 に答える