Memory error when resizing

Here is the set structure I wrote:

struct state_set
{
    struct state ***state_array;
    size_t *slot_sizes;
    size_t *slot_memory;
};

      

Here's the initializer:

struct state_set *state_set_init()
{
    struct state_set *new_set =
            malloc(sizeof(struct state_set));
    new_set->state_array = malloc(ARRAY_SIZE * sizeof(struct state**));
    new_set->slot_sizes = malloc(ARRAY_SIZE * sizeof(size_t));
    new_set->slot_memory = malloc(ARRAY_SIZE * sizeof(size_t));
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        new_set->slot_sizes[i] = 0;
        new_set->slot_memory[i] = INITIAL_SLOT_SIZE;
    }
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        new_set->state_array[i] =
                malloc(new_set->slot_memory[i] * sizeof(struct state*));
        error_validate_pointer(new_set->state_array[i]);
    }

    return new_set;
}

      

And there is a resize function that throws memory errors:

void state_set_resize_slot(struct state_set *set, int slot_i)
{
    struct state **to_resize = set->state_array[slot_i];
    to_resize =
            realloc(to_resize, set->slot_memory[slot_i] * 2 * sizeof(struct state*));
    error_validate_pointer(to_resize);
    set->slot_memory[slot_i] *= 2;
}

      

The question is, why state_set_resize_slot()

doesn't it work? I see no error with this realloc and I have been looking at this code for at least an hour. (And it's clear that realloc is the cause of all my problems). Or maybe the resize function is well written and I should look elsewhere for errors?

EDIT:

If anyone wants to take a look at the complete code, it is available here: http://pastebin.com/bfH3arDi (hash function returns 1 instead of h because I am testing collisions, also initializer and destructor function are deprecated, now I malloc 'use data for slot_memory and slot_sizes instead of using the stack).

And here valgrind outputs from running a program that adds a few states for installation (error around the third change):

==20979== Invalid write of size 8
==20979==    at 0x400C21: state_set_add (state_set.c:93)
==20979==    by 0x400781: main (main.c:22)
==20979==  Address 0x51f2320 is 0 bytes inside a block of size 40 free'd
==20979==    at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979==    by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979==    by 0x400B23: state_set_add (state_set.c:78)
==20979==    by 0x400781: main (main.c:22)
==20979== 
==20979== Invalid free() / delete / delete[] / realloc()
==20979==    at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979==    by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979==    by 0x400B23: state_set_add (state_set.c:78)
==20979==    by 0x4007B2: main (main.c:23)
==20979==  Address 0x51f2320 is 0 bytes inside a block of size 40 free'd
==20979==    at 0x4C2BB1C: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==20979==    by 0x4009CD: state_set_resize_slot (state_set.c:54)
==20979==    by 0x400B23: state_set_add (state_set.c:78)
==20979==    by 0x400781: main (main.c:22)
==20979== 
a.out: state_set.c:20: error_validate_pointer: Assertion `ptr != ((void *)0)' failed.

      

+3


source to share


1 answer


In your function, you take a pointer to to_resize

, then you take realloc

memory, but you never set a new pointer to set->state_array[slot_i]

, so it is lost and you continue to use the old, already freed memory space and will point out of bounds.



+2


source







All Articles