array++; causes array to advance by sizeof (a_pointer) so it now no longer points to address first returned by realloc(). That means any future attempt to realloc() with the new address of array will result in the error "Invalid pointer, pointer was not initially allocated with call to malloc, calloc or realloc".
Further, if array is not initialized NULL, then you cannot use realloc() for the initial allocation. Initializing n = 1; mixes a count with and index. Always keep the count so it is the next index to be filled. For 0 you can use an if / else or ternary, e.g.
n = 0;
...
if (n) { /* if n > 0 (not 1st allocation, use realloc) */
/* always realloc using a temporary pointer */
void *tmp = realloc (array, (n + 1) * sizeof *array);
if (!tmp) { /* validate EVERY allocation */
/* handle error, return */
}
array = tmp; /* assign reallocated block to array */
n += 1; /* increment count */
}
else { /* initial allocation */
array = malloc (sizeof *array);
if (!array) { /* validate EVERY allocation */
/* handle error, return */
}
n += 1; /* increment count */
}
/* rest of your strcpy here
* VALIDATE strlen(token) > 0 AND < 50
*/
/* note: you can consolidate both n += 1; here. duplicated for clarity */
You always call realloc() with a temporary pointer because when (not if) realloc() fails it returns NULL which will overwrite the address pointing to the allocated block of memory creating a memory leak. e.g. never do:
pointer = realloc (pointer, size);
Instead, by using a temporary pointer, if realloc() fails, pointer (your array) will still point to the last allocated and still valid block of memory allowing you to use what is stored there AND allowing you to free() that block of memory when you are done with it.
Note, you can use a ternary, but it is much less readable:
Words *array = NULL;
size_t n = 0;
...
void *tmp = realloc (array, sizeof *array * n ? n + 1 : 1);
if (!tmp) { /* validate EVERY allocation */
/* handle error, return */
}
array = tmp;
n += 1;
/* rest of your strcpy here
* VALIDATE strlen(token) > 0 AND < 50
*/
In C, there is no need to cast the return of malloc (or calloc or realloc), it is unnecessary. See: Do I cast the result of malloc?
++nwhich will give you the incremented value ofn.reallocthe only place where you allocate memory? Your variablearrayis uninitialized, which might explain the "invalid pointer" message. You must initialize it toNULL.arrayis a special pointer returned by realloc. If you want realloc again, you need pass oldarrayvalue without change. Something likeb = realloc(a, size1); c = realloc(b, size2);. You can not dob = realloc(a, size1); b++; c=realloc(b, size2);. Maybe you can make a backup first, likeb=realloc(a, size1); b_tmp=b++; c=realloc(b_tmp, size2);.