user13621710
user13621710

Reputation:

Error on realloc when try to allocate more memory

Iam developing a function where the size of array starts with 10, if the string of fgets its bigger he needs to allocate more memory, but I get a error, when the string is too big, like if I type something with 15 chars its ok, but with 30 I got the error! And I dont know why. So I hope you can tell me.

-= SOLVED ON THIS CODE =-

My main:

char *buf;

shellExecute(&buf);

My code:

 char* shellExecute(char** buf){
    
        int bufSize = 10;
        *buf = malloc(bufSize * sizeof(char));
        if(*buf == NULL){
            printf("[ERROR] can't malloc %d bytes\n", bufSize);
            exit(0);
        }
        char *readpos = *buf;
        
        while (1){  
        
        fgets(readpos, bufSize, stdin);
    
        /* Search from the end, as there's where the newline should be */
            if (readpos[strlen(readpos)-1] == '\n'){
                break;
            }   
    
        /* Need to allocate more memory */
             bufSize += bufSize;
             *buf = realloc(*buf, *buf + strlen(*buf) * sizeof(char));
    
        /* Set the pointer to next position to read into */
            readpos = *buf + strlen(*buf);
        /* Loop takes case of trying again */
        }   
    }

My error:

enter image description here

Upvotes: 0

Views: 85

Answers (1)

Nate Eldredge
Nate Eldredge

Reputation: 58741

The total size starts as 10. You do

fgets(readpos, bufSize, stdin);

On the first iteration, readpos points to the start of the buffer, so this is fine. Let's say 9 bytes are read, leaving space for the null terminator. You now do

bufSize += bufSize;
*buf = realloc(*buf, bufSize * sizeof(char));

So now bufSize is 20, and *buf has a total size of 20. Next you do

readpos = *buf + strlen(*buf);

so that readpos now points to *buf+9.

Your next fgets will attempt to read 20 bytes into a buffer of total size 20, but starting at offset 9, beyond which only 11 bytes are available. This may overrun the buffer by 9 bytes, causing undefined behavior.

Probably you want to keep a separate count of how many bytes have actually been read, and use this to calculate the space remaining in the buffer, which you will pass to fgets.

Another bug is that you need to check the return value of fgets to determine when the file has ended or if an error occurs. As it stands, when either of those things happens, your program will loop infinitely.

Upvotes: 4

Related Questions