Julian Gilmour
Julian Gilmour

Reputation: 13

Data being corrupted when using realloc()

In a project for class, I need to increase the capacity of a dynamic array of void pointers. Currently I'm having trouble with corrupting the users data when using realloc.

void dynarray_insert(struct dynarray* da, void* val) {
    int i;
    int size = da->size;
    int cap = da->capacity;


    /*if there is no more room*/
    if (size == cap) {
        cap = cap * 2;                  /*double capacity*/
        void** temp = realloc(da, sizeof(void*) * cap);

        da->data = temp;
    }

    /*if there is room*/
    else if (size < cap) {
        da->data[size] = val;
    }

    size++;

    da->size = size;
    da->capacity = cap;

  return;
}

there is my current code for the capacity increasing function,

struct dynarray {
  void** data;
  int size;
  int capacity;
};

and this is the dynarray struct.

EDIT: now that ive fixed the destination for realloc, I have a memory leak coming from realloc.

==474== HEAP SUMMARY:
==474==     in use at exit: 64 bytes in 1 blocks
==474==   total heap usage: 15 allocs, 14 frees, 848 bytes allocated
==474==
==474== 64 bytes in 1 blocks are definitely lost in loss record 1 of 1
==474==    at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==474==    by 0x1098E3: dynarray_insert (dynarray.c:96)
==474==    by 0x109303: test_dynarray (test_dynarray.c:39)
==474==    by 0x1097B6: main (test_dynarray.c:136)
==474==
==474== LEAK SUMMARY:
==474==    definitely lost: 64 bytes in 1 blocks
==474==    indirectly lost: 0 bytes in 0 blocks
==474==      possibly lost: 0 bytes in 0 blocks
==474==    still reachable: 0 bytes in 0 blocks
==474==         suppressed: 0 bytes in 0 blocks

Any ideas where this could be coming from?

Upvotes: 1

Views: 477

Answers (1)

chqrlie
chqrlie

Reputation: 144550

There are multiple issues:

  • You are not reallocating the element array, but the dynarray structure itself.
  • you do not store the element if you reallocate the array: if is quite error prone to separate the else clause as you did.
  • you do not check for a 0 initial capacity: cap * 2 would still be 0.

Here is a modified version:

#include <stdlib.h>

struct dynarray {
    void **data;
    int size;
    int capacity;
};

int dynarray_insert(struct dynarray *da, void *val) {
    int size = da->size;
    int cap = da->capacity;

    if (size == cap) {            /* if there is no more room */
        cap = cap ? cap * 2 : 8;  /* double capacity, special case for zero */
        void **temp = realloc(da->data, sizeof(void *) * cap);
        if (temp == NULL) {
            return -1;   /* return -1 upon realloc failure */
        }
        da->cap = cap;
        da->data = temp;
    }
    da->data[size] = val;
    return da->size++;   /* return the index of the new element if successful */
}

Upvotes: 2

Related Questions