Search code examples
cpointersrealloc

Problem with realloc of **struct


I have a problem with realloc function in C. I'm passing you a code bellow:

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

I'm not sending the first allocation code but if I increase the number of items that I'm using there everything works fine. When I call realloc I'm getting such error:

malloc: *** error for object 0x19dba8: pointer being reallocated was not allocated

Could you please help me to solve my problem?


Here is the creation method for Pool:

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

Like I told, if I want for example insert 1000 Items and allocate the memory by create function then everything works fine if I declare start Pool size for 100 elements and then I want to realloc Items I get the error.

Thank you very much for such quick answer.


Solution

  • But (*pool)->items was never allocated! You only allocated (*pool) - the whole slice of memory. You should have used two mallocs in this case - one for the control structure (Pool) and one for items* array.

    Clarification: you cannot realloc part of allocated memory - only the whole malloc'ed chunk. Also note that you should test the result of realloc first, before replacing the original pointer in well-written code - otherwise if realloc fails you lose the previously allocated memory block.