I need to dynamically append a char to a string, so I'm using realloc()
to add more memory as I need it.
I'm new to C (coming from Python) so I've been reading a lot and this was the best I could do:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void append_to(char *array, char value) {
size_t buffer = (strlen(array) * sizeof(char)) + sizeof(char);
char *new_array = realloc(array, buffer);
if (new_array == NULL) {
printf("CRITICAL ERROR\n");
exit(-1);
}
array = new_array;
int position = strlen(array);
array[position] = value;
}
int main() {
char *list = malloc(sizeof(char));
for (int i = 1; i < 26; i++){
append_to(list, 'a');
printf("%d -> %s\n", i, list);
}
}
This is just an example to showcase the issue. The code runs flawlessly until iteration 24, see below:
1 -> a
2 -> aa
[...] //omitted
23 -> aaaaaaaaaaaaaaaaaaaaaaa
24 -> aaaaaaaaaaaaaaaaaaaaaaaa
25 ->
What am I missing?
First you forget to add another NUL char at the end of your c-string.
Second, realloc may change the memory location of the data, but you passed the list
as value, so the relocation is not visible in the case of data relocation.
That should lokks like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void append_to(char **array, char value) { // pass pointer's address
size_t buffer = (strlen(*array) * sizeof(char)) + sizeof(char) + sizeof(char); // one more to tackle the end of the string
char *new_array = realloc(*array, buffer);
if (new_array == NULL) {
printf("CRITICAL ERROR\n");
exit(-1);
}
*array = new_array;
int position = strlen(*array);
(*array)[position] = value;
(*array)[position+1] = 0; // end of string
}
int main() {
char *list = malloc(sizeof(char));
list[0] = 0; // end of string
for (int i = 1; i < 26; i++){
append_to(&list, 'a'); // pass address of array so that it can be changed by the call
printf("%d -> %s\n", i, list);
}
free(list); // always explicitly free unused resources
}