Yes, malloc/calloc and free are involved, but realloc is the function you're looking for. See my example below for a way to implement an array that can grow. It's nice to know how to do such things in C, but if you want to migrate to C++, its STL containers will provide these kinds of dynamic sizing features for free.
/*
* import
*
* Accepts a set of numbers from standard input and stores in an array.
*
* Input may be redirected from a file, received through a pipe, or entered
* interactively. If used interactively, input must be terminated with
* ctrl-d after the final carriage return.
*
* Any number of numbers may be entered per line. Numbers may be separated
* by any number and combination of spaces, commas, or tabs. Leading blanks
* and blank lines are OK.
*
* Usage: ./import
*
*/
#include
#include
#include
#define NUMSTR_LEN 256
#define WHITESPACE " ,\t"
#define MIN_ARRAY_LEN 10
typedef struct {
int totalSize;
int inUse;
double *dArray;
} DoubleArray;
DoubleArray *new(int size);
void add(DoubleArray *, double);
int getSize(const DoubleArray * const); /* return total size of array */
int getLen(const DoubleArray * const); /* return number of array elements in use */
void print(DoubleArray *);
void delete(DoubleArray *);
int main(int argc, char *argv[]) {
char numstr[NUMSTR_LEN], /* entered line */
*s; /* pointer to next number in line */
double n; /* value of entered number */
DoubleArray *a = new(MIN_ARRAY_LEN);
/* Read each number on each line entered, and add each to the array. */
while ((s = fgets(numstr,NUMSTR_LEN,stdin)) != NULL) {
while (s != (char *)NULL) {
s = &s[strspn(s,WHITESPACE)];
if (sscanf(s,"%lf",&n) == 1) add(a,n);
s = strpbrk(s,WHITESPACE);
}
}
print(a);
delete(a);
exit(EXIT_SUCCESS);
}
DoubleArray *new(int size) {
DoubleArray *a = calloc(1,sizeof(*a));
a->dArray = calloc(size,sizeof(double));
a->totalSize = size;
a->inUse = 0;
return a;
}
void add(DoubleArray *a, double val) {
if (a->inUse == a->totalSize) {
a->dArray = realloc(a->dArray,
(a->totalSize += MIN_ARRAY_LEN) * sizeof(double));
}
a->dArray[a->inUse++] = val;
}
int getSize(const DoubleArray * const a) {
return a->totalSize;
}
int getLen(const DoubleArray * const a) {
return a->inUse;
}
void print(DoubleArray *a) {
int i, len=getLen(a),size=getSize(a);
printf("\nDoubleArray (%d of %d elements used):\n",len,size);
for (i = 0; i < len; i++) {
printf("\t%g\n",a->dArray[i]);
}
}
void delete(DoubleArray *a) {
free(a->dArray);
free(a);
}
#if 0
Sample run:
$ ./import
1 2 3 4 5
6 7 8 9 10 11
12 13
DoubleArray (13 of 20 elements used):
1
2
3
4
5
6
7
8
9
10
11
12
13
#endif