Reputation:
Goal: Enable user to input a huge amount of data (text type) in cmd.
I have somewhere in my code a function input_buff(buf, CMD_SIZE);
buf
is dynamically allocated buffer and CMD_SIZE
is fixed to 16.
char *buf = (char *)malloc(CMD_SIZE * sizeof(char));
static char *input_buff(char *buf, int size)
{
global_buf = buf; // global_buf is a static variable that will point to buf
.
.
.
// code handling inputting chars in a while loop
while(1)
{
insert(c) //c is the character to input.
}
}
For the function that inserts one char that will be included in while loop
static int insert(char c)
{
int len = strlen(global_buf);
if (//buffer exceeded CMD_SIZE))
{
char *new_buf = (char *)realloc(global_buf, (len+1) * sizeof(char)); // Increasing size by 1 byte
if (new_buf != NULL) {
global_buf = new_buf; // Only update global_buf if realloc succeeded
}
}
}
These two functions aim to enable user to keep entering chars even if it exceeded 16 by reallocating. Note that after writing the long text there is another function that stores the buffer in a history file.
When inserting a huge text no error occurs.
The error occurs when: I try to retrieve a long text from history file (>16)(similar to Up Arrow that retrieves the previous command in the history), I remove some characters then I try to add a character.
To debug, I printed the address of global_buf
to see if at this moment it exists or not and strlen(global_buf)
... everything seems correct, global_buf
is not corrupted and it exists and I still don't understand why a segmentation fault occurs.
I need only some brainstorming to see what can be the error.
Upvotes: 0
Views: 84
Reputation: 67835
char *buf = (char *)malloc(CMD_SIZE * sizeof(char));
malloc
. If you have to because the code does not compile it means that you use C++ compiler to compile C code which is incorrect.sizeof(char)
is by definition 1
. Rather use sizeof(*buf)
int len = strlen(global_buf);
null character
terminate the string and you use strlen
. It is undefined behaviour and the source of your problems.Correct example (not using your macro and global variables)
size_t insert(char **buf, char c)
{
size_t newbufsize = *buf ? strlen(*buf) + 2: 2;
char *new_buf = realloc(*buf, newbufsize * sizeof(*new_buf));
if (new_buf)
{
new_buf[newbufsize - 2] = c;
new_buf[newbufsize - 1] = 0;
*buf = new_buf;
}
else newbufsize = SIZE_MAX;
return newbufsize;
}
int main(void)
{
char *buf = NULL;
int c;
while((c = fgetc(stdin)) && c != EOF && c != '\n')
{
size_t buflen = insert(&buf, c);
if(buf) printf("buf size: %zu, strlen: %zu string: '%s'\n", buflen, strlen(buf), buf);
}
free(buf);
}
https://godbolt.org/z/fejMsf5jG
Upvotes: 1