Estaba escribiendo un analizador léxico en el que necesito agregar un carácter a una cadena (un carácter *). Por alguna razón, el siguiente código da como resultado una cadena que tiene un valor de "(nulo)" cuando lo imprimo en la salida estándar. La función se da a continuación.
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; }Cuando ejecuto las líneas
char *buf = NULL; append_char(buf, 'a'); append_char(buf, '\0'); printf("buffer: %s\n", buf); imprime (null) a stdout. ¿Cómo puedo arreglar esto?
pasar por valor
append_char(char *buffer, char c) no afecta el buf de la persona que llama en main() : append_char(buf, 'a'); . buf sigue siendo NULL . Esto lleva a la salida de OP.
Tamaño insuficiente
Tamaño insuficiente para la cadena recién asignada. No hay lugar para el carácter nulo .
Tamaño equivocado
Con char *buffer , sizeof(buffer) es el tamaño de un puntero, no la cantidad asignada de antemano.
memoria perdida
Cuando buffer = realloc(buffer, sizeof(buffer) + sizeof(char)); falla ( realloc() devuelve NULL ), el valor original del buffer se pierde. Guarde el resultado y pruebe.
Nota: OK para llamar a 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');Hay una serie de problemas con su programa:
buffer es una variable local de append_char() . Tan pronto como esta función regresa, la variable buffer se vuelve inutilizable. Debe pasar la dirección del buffer para escribir la dirección devuelta por malloc() y realloc() al buffer .buf es un puntero a un char . sizeof (buf) no depende de la cantidad de caracteres en buf .realloc() .free() después de que hayas terminado.Aquí hay una forma de lograr lo que está tratando de hacer (aunque no estoy tratando de solucionar todos los problemas que mencioné anteriormente):
#include <stdio.h> #include <stdlib.h> #include <string.h> void append_char(char **buffer, char c) { if(*buffer == NULL) { if((*buffer = malloc(sizeof(char) + 1)) == NULL) { /* + 1 for the NUL terminator */ fprintf(stderr, "COuld not allcocate memory to buffer\n"); return; } (*buffer)[0] = (*buffer)[1] = '\0'; } else { *buffer = realloc(*buffer, strlen(*buffer) + sizeof(char) + 1 /* for the NUL terminator */); } (*buffer)[strlen(*buffer) + 1] = '\0'; (*buffer)[strlen(*buffer)] = c; } int main(void) { char *buf = NULL; append_char(&buf, 'a'); append_char(&buf, '\0'); printf("buffer: %s\n", buf); }