Thread: *** glibc detected *** free(): invalid next size

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    15

    *** glibc detected *** free(): invalid next size

    Hi, everybody. I need help with this: I'm writing a program that reads something like <path [argument1] [argument2] [...][&]> from the standard input and then tries to execute the program 'path' with arguments 'argument1', 'argument2',... This program will be executed in background if the last character of the line is '&' and in foreground other case. The thing is, when I write something like <p a b> I get the message:

    *** glibc detected *** free(): invalid next size (normal): 0x0804a018
    *** glibc detected *** free(): invalid next size (fast): 0x0804a018
    Aborted

    When I just write <p> or <p a> it works just fine, but when I try to pass two or more arguments it cracks. My code is the following (if you have any suggestion to improve it, please tell me - and be gentle: I'm not experienced and I use to make the dumbest mistakes :P):

    Code:
    #include<unistd.h>
    #include<stdio.h>
    #include<stdlib.h>
    
    #define SIZEBUF 1024
    
    typedef enum {FALSE=0, TRUE} bool;
    
    int main(int argc, char* argv[]){
    
        char buffer[SIZEBUF];
        char **arguments;
        char *path;
        int i, currentarg, numargs, bytesread;
        pid_t pid;
        bool background;
    
        if(setvbuf(stdout, NULL, _IONBF, 0)){
            perror("error en setvbuf");
            exit(-1);
        }
    
        while(1){
    
            printf("\n-------------------------------\n");
            printf("------- esperando input -------\n");
            printf("-------------------------------\n\n");
    
            //leemos de la entrada estándar
            if((bytesread = read(STDOUT_FILENO, buffer, SIZEBUF) - 1) < 0){
                perror("error en el read");
                exit(-1);
            }
    
            //cortamos el buffer por donde corresponda (el '\n')
            buffer[bytesread] = '\0';
    
            if(!strcmp(buffer, "exit"))
                break;
    
            background = FALSE;
    
            if(buffer[bytesread-1] == '&'){ //comprobamos tiene que ejecutarse en background o no y quitamos el '&' (si lo hay)
                background = TRUE;
                bytesread--;
                buffer[bytesread] = '\0'; //cortamos el buffer por donde corresponda
            }
    
            printf("==========%s===========\n\n", background?"background":"foreground");
    
            numargs = 1;
            for(i=0; i<bytesread; i++){
                if(buffer[i] == ' ') //contamos el número de argumentos para saber cuánta memoria reservar
                    numargs++;
            }
            arguments = malloc(numargs+1);
            currentarg = 1;
            arguments[0] = &(buffer[0]);
            for(i=0; i<bytesread; i++){ //creamos el vector de punteros a los argumentos
                if(buffer[i] == ' '){
                    arguments[currentarg] = &(buffer[i+1]);
                    currentarg++;
                    buffer[i] = '\0'; //separamos los argumentos por el carácter terminador ('\0')
                }
            }
    
            path = arguments[0];
            arguments[numargs] = NULL;
            printf("path: %s\n", path);//quitar
    
            if((pid = fork()) < 0){
                perror("error en el fork");
                exit(-1);
            }else if(pid == 0){ //estamos en el hijo
                sleep(1); //ponemos un retraso para ver más claramente los efectos de ejecutarlo en background
                if(execv(path, arguments) < 0){ //ejecutamos el otro programa
                    perror("error en execv");
                    exit(-1);
                }
            }else if(!background){//estamos en el padre y queremos ejecutar el hijo en foreground, así que...
                wait(NULL); //...esperamos a que termine
            } //si queríamos ejecutarlo en background (o si ya ha terminado) seguimos
            free(arguments);
    
        }
    
        return 0;
    }
    Thanks a lot!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > arguments = malloc(numargs+1);
    You forgot to scale it by the size of the things you're allocating.
    So the amount you allocate is much less than you expect.

    arguments = malloc( (numargs+1) * sizeof *arguments );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    15
    OMG. You're absolutely right. I forgot because I use to program in c++, and I use 'new' instead of 'malloc' (with 'new' you have to specify the type, so the size is implicit). Thanks a lot, that was easy!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. glibc detected.
    By eXeCuTeR in forum C Programming
    Replies: 19
    Last Post: 07-09-2008, 01:38 PM
  2. glibc invalid pointer error
    By benshi in forum C++ Programming
    Replies: 4
    Last Post: 05-12-2008, 10:24 AM
  3. Replies: 11
    Last Post: 03-25-2003, 05:13 PM
  4. Changing a Structures Members array size
    By Xei in forum C++ Programming
    Replies: 1
    Last Post: 11-07-2002, 07:45 PM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM