Title: Dynamic array of *points crashing & leaking memory after reallocation - why?
Tags: c;memory-leaks
Question: Edit: To clarify, I'm after an array of pointers, of type ```Point3d``` structs.
I messed up something that seemed so simple. I've read several posts here on dynamically allocated arrays, but I still can't see where I went wrong.
In the code below I'm trying to make a dynamically allocated pointer array of Point3d structs. That's all. But I'm messing up the memory allocation (valgrind reports 40 bytes lost etc) and when reallocating the array more than once (ALLOC_COUNT &gt; 1) it crashes on deallocation. Where am I doing it wrong?
I aim for C99 only. Did this on Windows, CLion with valgrind on WSL.
The complete program:
```#include <stdio.h&gt;
#include <stdlib.h&gt;

typedef struct Point3d_t {
    double X;
    double Y;
    double Z;
} Point3d;

size_t increment_size = 0;
size_t vertex_count = 0;
size_t current_size = 0;
```
```
void *destructVertices(Point3d **vertices) {
    if (vertices != NULL &amp;&amp; ((current_size &gt; 0) || (vertex_count &gt; 0))) {
        for (int i = 0; i < current_size; ++i) {
            free(vertices[i]);
            vertices[i] = NULL;
        }
    }
    return NULL;
}

size_t allocateVertices(Point3d **vertices) {
    const size_t new_size = current_size + 1 + increment_size;
    Point3d **expanded_items = realloc(*vertices, new_size * sizeof(Point3d *));
    if (!expanded_items) { // Allocation failed.
        free(*vertices); fprintf(stderr, &quot;RIL: Error reallocating lines array\n&quot;);
        expanded_items = NULL; exit(0);
    }
    else if (expanded_items == vertices) {
        expanded_items = NULL; // Same mem addr, no need to change
    }
    else {
        vertices = expanded_items; // mem allocated to new address, point there
    }
    current_size = new_size;
    return current_size;
}
```
```/// returning the last item count, which can also be interpreted
/// as true (&gt;0) or false (0) by the caller
size_t addVertex(Point3d point, Point3d **vertices) {
    if (vertex_count == current_size) {
        if (!allocateVertices(vertices)) return 0;
    }
    Point3d* p = malloc(sizeof(Point3d));
    if (!p) exit(99);
    p-&gt;X = point.X;
    p-&gt;Y = point.Y;
    p-&gt;Z = point.Z;
    vertices[vertex_count] = p;
    vertex_count += 1;
    return vertex_count; // last item count
}

Point3d *m_vertices[1];
```
Increasing ALLOC_COUNT to something larger than 1 (causing realloc) will crash on deallocate.
```#define PT_COUNT 4
#define ALLOC_COUNT 1


int main() {
    increment_size = PT_COUNT;
    current_size = 0;
    vertex_count = 0;

    printf(&quot;Size of Point3d        = %zu\n&quot;, sizeof(Point3d)); // fake error
    printf(&quot;Size of *Point3d       = %zu\n&quot;, sizeof(Point3d *)); // fake error
    printf(&quot;Size of **m_vertices   = %zu\n&quot;, sizeof(m_vertices)); // fake error
    printf(&quot;Size of *m_vertices    = %zu\n&quot;, sizeof(*m_vertices)); // fake error
    printf(&quot;Size of *m_vertices[0] = %zu\n&quot;, sizeof(*m_vertices[0])); // fake error
    printf(&quot;---------------------------\n&quot;); // fake error

    m_vertices[0] = NULL; //malloc(sizeof(Point3d*));

    // new points
    for (int i = 0; i < (PT_COUNT * ALLOC_COUNT); ++i) {
        Point3d p;
        p.X = 1.0 + (i * 0.001);
        p.Y = 2.0 + (i * 0.001);
        p.Z = 3.0 + (i * 0.001);
        const size_t n = addVertex(p, m_vertices);
        if (!n) exit(1);
    }

    printf(&quot;vertices.Capacity      = %zu\n&quot;, current_size);
    printf(&quot;vertices.Count         = %zu\n&quot;, vertex_count);

    destructVertices(m_vertices);
    //free(*m_vertices);
    return 0;
}
```


Here is the accepted answer: The final code (some fwd declarations and function prototypes omitted).
As indicated earlier, the aim was managing a dynamic array of pointers, without the leaks. Tested with Valgrind (which complains only on the uninitialized space resulting from ```realloc```, although I actually assign ```(void*)NULL``` to the newly (re)allocated space, but anyway).
Some function pointer prototypes (```fn_...```) omitted. The code style is odd, but I need to paste in a lot of code from some existing C# prototyping so I use C# style in part to make it easier to copy-paste in both directions.
```typedef struct Point3d_t Point3d;
typedef struct Point3d_t
    double X;
    double Y;
    double Z;
} Point3d;

// This &quot;list owner&quot; was omitted in the OP.
typedef struct MeshVertexList_t {
    size_t AllocationsCount;
    size_t Capacity;
    size_t Count;
    size_t Increment;
    f_Add Add;
    f_allocateVertices allocateVertices;
    f_Destroy Destroy;
    Point3d **Items; // array of ptr
} MeshVertexList;
```
```MeshVertexList *New_MeshVertexList(size_t increment) {
    MeshVertexList *mvlist = malloc(sizeof(MeshVertexList));
    mvlist-&gt;AllocationsCount = 0;
    mvlist-&gt;Capacity = 0;
    mvlist-&gt;Count = 0;
    mvlist-&gt;Increment = increment;
    mvlist-&gt;Add = Add;
    mvlist-&gt;Destroy = Destruct_MeshVertexList;
    mvlist-&gt;allocateVertices = allocateVertices;
    mvlist-&gt;Items = NULL;
    return mvlist;
}
```
```// Assigned to function pointer
size_t Add(MeshVertexList *self, Point3d *point) {
    if (self-&gt;Count == self-&gt;Capacity) {
        int res = (int) allocateVertices(self);
        if (!res) return 0;
    }
    self-&gt;Items[self-&gt;Count] = point;
    self-&gt;Count++;
    return self-&gt;Count; // last item count
}
```
```// Assigned to function pointer
size_t allocateVertices(MeshVertexList *Vertices) {
    size_t new_capacity = 1;
    if (Vertices-&gt;Capacity &gt; 0) new_capacity = Vertices-&gt;Capacity + Vertices-&gt;Increment;
    void *items_tmp = realloc(Vertices-&gt;Items, sizeof(*Vertices-&gt;Items) + new_capacity * sizeof(Point3d*));
    if (!items_tmp) {
        Destruct_MeshVertexList(Vertices);
        perror(&quot;RIL: Error reallocating lines array\n&quot;);
        exit(EXIT_ALLOC_ERROR);
    } else if (items_tmp == Vertices-&gt;Items) {
        items_tmp = NULL; // Same mem addr, no need to change
    } else {
        Vertices-&gt;Items = items_tmp;
    }
    for (int i = Vertices-&gt;Capacity; i < new_capacity; ++i) {
        Vertices-&gt;Items[i] = (void *)NULL; // Valgrind doesn't detect this!
    }
    Vertices-&gt;AllocationsCount++;
    Vertices-&gt;Capacity = new_capacity;
    return Vertices-&gt;Capacity;
}
```
```// Assigned to function pointer
void Destruct_MeshVertexList(MeshVertexList *Vertices) {
    for (int i = 0; i <= Vertices-&gt;Capacity; ++i) {
        if (Vertices-&gt;Items[i] != NULL) {
            free(Vertices-&gt;Items[i]); // deallocating point
            Vertices-&gt;Items[i] = NULL;
        }
    }
    Vertices-&gt;Capacity = 0;
    Vertices-&gt;Count = 0;
    Vertices-&gt;Increment = 0;
    Vertices-&gt;Add = NULL;
    
    Vertices-&gt;allocateVertices = NULL;
    free(Vertices-&gt;Items);
    Vertices-&gt;Items = NULL;
    free(Vertices);
    Vertices = NULL;
}
```
```
typedef struct MeshObj_t {
    MeshVertexList *Vertices;
} MeshObj;

#define ALLOC_INCREMENT 1 // <-- debug: realloc for each added pt
#define PT_COUNT 10

int main() {
    const clock_t start = clock();
    MeshObj m;
    m.Vertices = New_MeshVertexList(ALLOC_INCREMENT);
    
    printf(&quot;Size of Point3d        = %zu\n&quot;, sizeof(Point3d));
    printf(&quot;Size of *Point3d       = %zu\n&quot;, sizeof(Point3d *));
    printf(&quot;Size of m_vertices     = %zu\n&quot;, sizeof(m.Vertices));
    //printf(&quot;Size of *m_vertices[0] = %zu\n&quot;, sizeof(*m_vertices[0]));
    printf(&quot;---------------------------\n&quot;);
    
    for (int i = 0; i < (PT_COUNT); ++i) {
        Point3d *p = malloc(sizeof(Point3d));
        p-&gt;X = 1.0 + (i * 0.001);
        p-&gt;Y = 2.0 + (i * 0.001);
        p-&gt;Z = 3.0 + (i * 0.001);
        size_t n = m.Vertices-&gt;Add(m.Vertices, p);
        p = NULL;
        if (!n) exit(1);
    }
```
```    const clock_t stop = clock();
    const double elapsed_time = (double) (stop - start) / CLOCKS_PER_SEC;
    printf(&quot;Vertices-&gt;Capacity  : %zu\n&quot;, m.Vertices-&gt;Capacity);
    printf(&quot;Vertices-&gt;Count     : %zu\n&quot;, m.Vertices-&gt;Count);
    printf(&quot;Elapsed time        : %lf ms\n&quot;, elapsed_time);
    printf(&quot;---------------------------\n&quot;);
    for (int i = 0; i < m.Vertices-&gt;Count; ++i) {
        printf(&quot;%f %f %f\n&quot;, m.Vertices-&gt;Items[i]-&gt;X, m.Vertices-&gt;Items[i]-&gt;Y, m.Vertices-&gt;Items[i]-&gt;Z);
    }
    
    m.Vertices-&gt;Destroy(m.Vertices);
    m.Vertices = NULL;
    return 0;
}
```



{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2021:00:01/13/21', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<c><memory-leaks>', 'Title': 'Dynamic array of *points crashing & leaking memory after reallocation - why?', 'ViewCount': 80, 'id': 65700282, 'user_AboutMe': '<p>Delphi OOP/ORM guy (designed commercial realtime (ERP) business system). Interested in Go. Using VBA &amp; VBScript, automating Enterprise Architect &amp; MS Office. Playing around with js and C#.</p>\n', 'user_AccountId': 1360526.0, 'user_DisplayName': 'RIL', 'user_Reputation': 185.0, 'user_Views': 44.0, 'user_id': 1297993.0}}