One long-term problem is that you are not returning the updated array pointer from the addPointerToArray() function:
void addPointerToArray(Vertex v1, Vertex out[], int *size) { int newSize = *size; newSize++; out = realloc(out, newSize * sizeof(Vertex)); out[(*size)] = v1;
When you redistribute a space, it can move to a new location, so the return value from realloc() should not be the same as the input pointer. This may work unless there is another memory allocation when you add to the array, because realloc() will expand the existing allocation, while there is room for that, but it will fail as soon as you start allocating other data when reading vertices There are several ways to fix this:
Vertex *addPointerToArray(Vertex v1, Vertex out[], int *size) { int newSize = *size; newSize++; out = realloc(out, newSize * sizeof(Vertex)); out[(*size)] = v1;
and call:
out = addPointerToArray(vertexToAdd, out, size);
Alternatively, you can pass a pointer to an array:
void addPointerToArray(Vertex v1, Vertex **out, int *size) { int newSize = *size; newSize++; *out = realloc(*out, newSize * sizeof(Vertex)); (*out)[(*size)] = v1;
and call:
out = addPointerToArray(vertexToAdd, &out, size);
None of these rewrites address a subtle memory leak. The problem is that if you overwrite the value you pass to realloc() with the return value, but realloc() fails, you lose the pointer to the (still) allocated array - a memory leak. When you use realloc() , use an idiom like:
Vertex *new_space = realloc(out, newSize * sizeof(Vertex)); if (new_space != 0) out = new_space; else ...deal with error...but out has not been destroyed!...
Note that using realloc() to add one new item at a time results in (may lead to) quadratic behavior. You would be better off allocating a large chunk of memory - for example, double the allocated space:
int newSize = *size * 2;
If you are worried about redistribution, at the end of the reading cycle you can use realloc() to reduce the allocated space to the exact size of the array. However, there is a bit more accounting to do; you need values: the number of vertices allocated for the array, and the number of vertices actually used.
Finally, at the moment, at least note that you really have to be ruthless and use addPointerToArray() to add the first three entries to the array. I would probably use something similar to this (unverified) code:
struct VertexList { size_t num_alloc; size_t num_inuse; Vertex *list; }; void initVertexList(VertexList *array) {
This uses the counter-intuitive realloc() property so that it executes malloc() if the pointer passes at zero. Instead, you can check array->list == 0 and use malloc() and then realloc() otherwise.
You may notice that this structure also simplifies the calling code; you no longer have to deal with a separate int *size; in the main program (and its memory allocation); size is effectively bound to the VertexList structure as num_inuse . Now the main program can start:
int main(void) { VertexList array; initVertexList(&array); addPointerToArray((Vertex){ 1, 1 }, &array); // C99 compound literal addPointerToArray((Vertex){ 2, 2 }, &array); addPointerToArray((Vertex){ 3, 3 }, &array); addPointerToArray((Vertex){ 9, 9 }, &array); for (int i = 0; i < array->num_inuse; i++) printf("Vertex %d: (%d, %d)\n", i, array->list[i].x, array->list[i].y, i); return 0; }
(It seems that this sequence will only cause memory allocation once, because the new size (old_size + 2) * 2 allocates 4 elements to the array for the first time. It is easy to redistribute by adding a new point or by refining the formula to (old_size + 1) * 2 , or ...
If you plan to recover from a memory allocation failure (and not just exit if that happens), then you must modify addPointerToArray() to return the status (successful, not successful).
In addition, the function name must be addPointToArray() or addVertexToArray() or even addVertexToList() .