I was writing a lexical analyzer in which I need to append a char to a string (a char *). For some reason, the code below is resulting in string having a value of "(null)" when I print it to stdout. The function is given below.
void append_char(char *buffer, char c) {
if(buffer == NULL) {
buffer = malloc(sizeof(char));
if(buffer == NULL) {
fprintf(stderr, "COuld not allcocate memory to buffer\n");
}
} else {
buffer = realloc(buffer, sizeof(buffer) sizeof(char));
}
buffer[sizeof(buffer) - 1] = c;
}
When I run the lines
char *buf = NULL;
append_char(buf, 'a');
append_char(buf, '\0');
printf("buffer: %s\n", buf);
it prints (null)
to stdout. How can I fix this?
CodePudding user response:
Pass by value
append_char(char *buffer, char c)
does not affect the caller's buf
in main()
: append_char(buf, 'a');
. buf
remains NULL
. This leads to OP's output.
Insufficient size
Insufficient size for the newly allocated string. No room for the null character.
Wrong size
With char *buffer
, sizeof(buffer)
is the size of a pointer, not the amount allocated beforehand.
Lost memoery
When buffer = realloc(buffer, sizeof(buffer) sizeof(char));
fails (realloc()
returns NULL
) , the original value of buffer
is lost. Save the result and test.
Note: OK to call realloc(NULL, ...)
.
char *append_char(char *buffer, char c) {
size_t old_length = buffer ? strlen(buffer) : 0;
size_t new_length = old_length 1; // 1 for c
// Size needed for a string is its length 1
char *new_buffer = realloc(buffer, new_length 1); // 1 for \0
if (new_buffer == NULL) {
fprintf(stderr, "Could not allocate memory to buffer\n");
free(buffer);
return NULL;
}
new_buffer[old_length] = c;
new_buffer[old_length 1] = '\0';
return new_buffer;
}
// Usage
buf = append_char(buf, 'a');