I've written this function intended to add strings to an array of strings, each time creating enough memory for the new string before putting it in, and realloc
ing the size of the array when it gets full. Here's an example of my code:
#define INITIAL 10
int addtoarray(char **A, int *size, int n, char *b);
int
main(int argc, char **argv) {
char **D, a[3]="ab"; /*'a' is arbitrary for this example */
int n=0, size=INITIAL, i, j;
D = (char**)malloc(INITIAL*sizeof(char));
for (i=0; i<3; i++) {
n = addtoarray(D, &size, n, a);
/* print the contents of D */
printf("Dict: ");
for (j=0; j<n; j++) {
printf("D[%d]='%s' ", j, D[j]);
} printf("\n");
}
return 0;
}
int
addtoarray(char **A, int *size, int n, char *b) {
if (*size == n) {
/* Array is full, give more space */
realloc(A, *size = 2*(*size));
assert(A);
}
printf("Adding '%s' to D[%d], size of D = %d\n", b, n, *size);
/* Create space in array for new string */
A[n] = (char*)malloc(strlen(b)+1);
assert(A[n]);
/* Put the new string in array! */
strcpy(A[n], b);
n++;
return n;
}
In this example 'n' is the number of strings in the array. The output of this code is:
Adding 'ab' to D[0], size of D = 10
D: D[0]='ab'
Adding 'ab' to D[1], size of D = 10
D: D[0]='ab' D[1]='ab'
Adding 'ab' to D[2], size of D = 10
D: D[0]='?K@S?' D[1]='ab' D[2]='ab'
As you can see the third time the function is called, the string goes into the array fine. But the first string in the array is somehow changed. I have no idea why this has happened, but I am pretty sure it is happening on the A[n] = (char*)malloc(strlen(b)+1);
line in the function.
Does anyone know what I've done wrong? (Also if you have any tips for other parts of my code)
If you want an array of string, you need room for size of char *
:
malloc(INITIAL*sizeof(char));
should be
malloc(INITIAL*sizeof(char *));
And in the realloc
part:
realloc(A, *size = 2*(*size));
as pointed out by Jonathan Leffler, realloc
returns a pointer to the reallocated memory block, you need a triple pointer to pass (and manipulate its value with the dereference operator) a pointer to string:
int addtoarray(char ***A, int *size, int n, char *b) {
...
*A = realloc(*A, (*size = 2*(*size)) * sizeof(char *));
assert(*A);
...
and in your main
function:
n = addtoarray(&D, &size, n, a);