Home > Back-end >  Where am I accessing illegal memory? realloc(): invalid next size
Where am I accessing illegal memory? realloc(): invalid next size

Time:03-23

I'm making a shell simulator for an operating systems course homework. We were asked to add a "history" command that when typed, should print a list of commands that the user entered.

I decided to implement it using a history array that allocates dynamically more memory depending on the size of the new command.

Here is my code:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

#define BUFFER_SIZE 100

//comment

int main(void)
{
    close(2);
    dup(1);
    char command[BUFFER_SIZE];
    char* hist = NULL;
    // int counter = 0;

    while (1)
    {
        fprintf(stdout, "my-shell> ");
        memset(command, '\0', BUFFER_SIZE);
        fgets(command, BUFFER_SIZE, stdin);
        if(strncmp(command, "exit", 4) == 0)
        {
            break;
        }
        
        //alocate memory for the current position in the hist array
        if(hist == NULL){
            hist = (char*)malloc(sizeof(char)*strlen(command));
        }
        else{
            hist = realloc(hist,sizeof(char)*strlen(command));
        }
        strcat(hist,command);
        printf("the size of the boy: %d\n",(int) strlen(hist));
        // counter  = strlen(command);

        int pid = fork();

        char *argv[BUFFER_SIZE];
        char *pch;

        pch = strtok(command, " \n");

        int i;
        for(i=0; pch != NULL; i  ){
            argv[i] = pch;
            pch = strtok(NULL, " \n");
        }
        argv[i] = NULL;

        int hasAmpersand = 0;
        //check if the last entered character was '&'
        if(*argv[i-1]=='&'){
            // printf("entered &:");
            hasAmpersand = 1;
            //replace it with '\0'
            argv[i-1] = NULL;
        }
        
        if(pid == 0){ //child process execute sys call
            if(strncmp(argv[0],"history",7) == 0){
                printf("%s\n", hist);
                exit(1);
            }
            else{
                execvp(argv[0], argv);
                printf("\nbad syntax\n");
            }
        }
        else{
            if(!hasAmpersand){ //wait for child
                while(wait(NULL) != pid);
            }
        }
    }
    free(hist);

    return 0;
}

The implementation works for up to 6 commands stored in hist but it crashed with the error

realloc(): invalid next size
aborted

I was wondering what causes the issue and I'd love suggestions on fixing it. Thanks.

CodePudding user response:

The second parameter of realloc should be the new size of the entire block, not just the size of data you are "adding" to memory area.

hist = realloc(hist, currentHistSize sizeof(char)*strlen(command));

Make sure you name currentHistSize as you want.

CodePudding user response:

You need room for the trailing string terminator '\0', so add one to the allocated size:

hist = malloc(sizeof(char)*strlen(command)   1);

The argument to realloc also needs to be adjusted. Also you probably want to remove the trailing newline after calling fgets.

  • Related