-1

im getting a "debug assertion error" when this code compiles, with the expression _CrtIsValidHeapPointer(block), can anyone explain why this has happened, and how to resolve

typedef struct _POOL
{
    int size;
    void* memory;

} Pool;

Pool * allocatePool(int n)
{

    int *p = (int*)malloc(sizeof(int) * n);

    Pool pool = { sizeof(*p), *p };

    return &pool;

}

void freePool(Pool* pool)
{
    free(pool);
}
David
  • 11
  • 5

3 Answers3

4

There are 2 errors in your approach:

  1. You return a pointer to a variable with automatic storage.
  2. You call free() on a pointer that doesn't point to dynamic memory.

What this means is you should also allocate the space for your Pool object dynamically. In your freePool you must then free both the memory pointed to by void *memory and the Pool * itself.

Pool *allocatePool(int n)
{
    Pool *pool = malloc(sizeof *pool);

    if (!pool) {
        /* malloc failed, bail out */
        return NULL;
    }

    /* Caller is responsible for passing non negative value as n.
       Negative values will have suprising effects. */
    int *p = malloc(sizeof *p * n);

    /* Failed malloc, or n was 0 and current implementation returns
       NULL. */
    if (!p) {
        /* Clean up already allocated memory */
        free(pool);
        /* Many dislike multiple return points in a function, but
           I think for this little example it's ok. That, or gotos. */
        return NULL;
    }

    /* Storing the size of single item seems dubious. Size of the whole
       allocated area in objects is much more useful. */
    pool->size = n;
    pool->memory = p;
    return pool;    
}

and

void freePool(Pool *pool)
{
    free(pool->memory);
    free(pool);
}
Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127
1

You need this:

Pool * allocatePool(int n)
{
    int *p = malloc(sizeof(int) * n);
    Pool *pool = malloc(sizeof(Pool));
    pool->memory = p;
    pool->size = n;
    return pool;
}

BTW: the casts of malloc are not necessary.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • @David they necessary are in C++ but not in C. See [this SO question](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Jabberwocky Apr 04 '16 at 11:22
0

These two functions

Pool * allocatePool(int n)
{

    int *p = (int*)malloc(sizeof(int) * n);

    Pool pool = { sizeof(*p), *p };

    return &pool;

}

void freePool(Pool* pool)
{
    free(pool);
}

does not make sense.

For example the first function returns pointer to a local object of type Pool that will not alive after exiting the function. Moreover this initialization is invalid

Pool pool = { sizeof(*p), *p };

I think you meant at least the following

Pool pool = { n, p };

or maybe

Pool pool = { n * sizeof( int ), p };

The functions can look the following way

Pool allocatePool( int n )
{
    Pool pool = { 0, NULL };
    void *p;

    if ( n > 0 && ( p = malloc( n * sizeof( int ) ) ) != NULL )
    {
        pool.size = n;
        pool.memory = p;
    }

    return pool;
}

void freePool( Pool *pool )
{
    free( pool->memory );
    pool->size = 0;
    pool->memory = NULL;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335