glibc detected, realloc(): invalid pointer

2020-06-05 06:43发布

问题:

I apologize for the lengthy code. I have a simple question, but I thought I include my code so it will be clear where I am coming from. I get a realloc corruption. I think the corruption is because I am not freeing correctly. In reality I am not sure what glibc even says or means. Can any one briefly explain that to me? Again sorry for the lengthy code.


#include "draw2.h"
#include "draw2a.h"
#include "draw2b.h"

const char Exec_c[]  = "java -jar Sketchpad.jar";

void parseFile(FILE * fp, FILE *sketcher){ 
    char line [MAX_WORD] = {"NULL"}; 
    char word [MAX_WORD] = {"NULL"};
    char figureName [MAX_WORD] = {"NULL"};
    struct figure *pointsAndname;                     
    long int countNumberoffigures = 0;
    printOutput();
    long int temp = 10;
    pointsAndname = malloc(temp * sizeof(struct figure));
    assert(pointsAndname != NULL);
    while ( fgets(line, MAX_WORD - 1, fp) != NULL ){
        int nuRead = sscanf(line, "%s", word);
        assert(pointsAndname != NULL);
        if ( nuRead > 0 ){
            if(strncmp(word, "Figure", MAX_WORD)==0){ 
                countNumberoffigures += 1;                      
                if (temp == countNumberoffigures - 1){
                    temp = temp * 2;
                    printf("pointsAndname is %x\n", pointsAndname);
                    pointsAndname = realloc(&pointsAndname, temp * sizeof(struct figure));
                    printf("pointsAndname is %x after realloc\n", pointsAndname);
                }
                assert(pointsAndname != NULL);
                figureFunction(fp,line, word, figureName, countNumberoffigures, pointsAndname + countNumberoffigures);  
            }                                                 
            if(strncmp(word, "printFigure", MAX_WORD)==0){      //4)read the command printFigure, name of the figure
                if (countNumberoffigures == 1){
                    printFigure(fp, line, countNumberoffigures, pointsAndname + countNumberoffigures);
                }else{
                    printFigure(fp, line, countNumberoffigures, pointsAndname + countNumberoffigures - 1);
                }
            }
            if(strncmp(word, "drawFigure", MAX_WORD)==0){       //5)read the command drawFigure and the name of the figure
                if (countNumberoffigures == 1){
                    drawFigure(sketcher, line, countNumberoffigures, pointsAndname + countNumberoffigures);
                }else{
                    drawFigure(sketcher, line, countNumberoffigures, pointsAndname + countNumberoffigures - 1);
                }
            }
            if(strncmp(word, "translate", MAX_WORD)==0){        //6)read the command translate 
                if (countNumberoffigures == 1){
                    translate(line, sketcher, countNumberoffigures, pointsAndname + countNumberoffigures);
                }else{
                    translate(line, sketcher, countNumberoffigures, pointsAndname + countNumberoffigures - 1);
                }
            }
            if(strncmp(word, "child", MAX_WORD)==0){            //7)reads command child and the name of the figure
                child(line, word, figureName, sketcher);
            }
            if(strncmp(word, "#", MAX_WORD)==0){                //8)reads the whole line until the \n
                printf(line);
                //printf("ani po\n");
            }
            if(strncmp(word, "end", MAX_WORD)==0){
                fprintf (sketcher, "end\n");
                //printf("ani po\n");
            }
            if(strncmp(word, "rotate", MAX_WORD)==0){
                if (countNumberoffigures == 1){
                    rotate(line, sketcher, countNumberoffigures, pointsAndname + countNumberoffigures);
                }else{
                    rotate(line, sketcher, countNumberoffigures, pointsAndname + countNumberoffigures - 1);
                }
            }
        }
    }
    free(pointsAndname->vertices);
    free(pointsAndname);
}

void processArgument(char argument[]){
    FILE *sketcher;
    FILE *fp;
    fp = fopen (argument, "r");
    sketcher = popen(Exec_c, "w");
    if (fp == NULL){
        printf ("Could not open pipe to %s\n", argument);
        exit (EXIT_FAILURE);
    }
    if (sketcher == NULL){
        printf ("Could not open pipe to %s\n", argument);
        exit (EXIT_FAILURE);
    }else{
        parseFile(fp, sketcher);
        if(fclose(fp)==EOF){
            printf("couldn't close pipe to %s.\n", argument);
            exit(EXIT_FAILURE);
        }
        if (pclose(sketcher) == -1){                                                 //if (pclose(sketcher) == -1){
            fprintf(stderr, "draw_line error: couldn't close pipe to %s.\n", Exec_c);//fprintf(stderr,"",E);
            exit(EXIT_FAILURE);    
        }
    }
}

int main (int argc,  char *argv[]){
    int i;
    if ( argc < 2 ){
        printf ("%s\n", "0 comment(s)");
        exit(EXIT_FAILURE);
    }else{
        for (i = 1; i < argc; i++){
            processArgument(argv[i]);
        }
    }
    return 0;
}

#include "draw2.h"
#include "draw2a.h"

void printOutput(){
    printf("./draw2 started on:");

    fflush(stdout);
    system("date\n");
}
/*send what ever there is after the child to sketchpad(in that specific line)*/
void child (char line[], char word[], char nameFigure[], FILE * sketcher){          
    sscanf(line, "%s%s", word, nameFigure);
    fprintf (sketcher, "%s\n", &line[6]);
} 

/*I construct the struct by reading from the Figure line to the end figure line.*/
void figureFunction (FILE * fp, char line[], char word[], char figureName[], long int countNumberoffigures, struct figure *figureHere){
    double startx, starty;
    long int temp = 10;
    figureHere->vertices = malloc(temp * sizeof(struct pointxy));
    sscanf(line, "%s%s%lf%lf%*s", word, figureHere->figureName, &startx, &starty);
    printf("This is the figureHere->vertices inside the figureFunction: %s\n", figureHere->vertices);
    (*(figureHere->vertices)).x = startx;              
    (*(figureHere->vertices)).y = starty;
    fgets(line, MAX_WORD - 1, fp);                  
    int nuRead = sscanf(line, "%s", word);              
    long int i = 1;                                                     
    while (strncmp(word, "End", MAX_WORD)!=0){ 
        if (strncmp(word, "#", MAX_WORD) == 0){
            printf("%s",line);
        }           
        if (strncmp(word, "draw", MAX_WORD) == 0){
            //printf("lepo ani magia?????\n\n");
            sscanf (line, "%s%lf%lf", word, &startx, &starty);
            //printf("this is my startx and starty: %lf %lf\n\n",startx, starty);
            figureHere->vertices[i].x = figureHere->vertices[i-1].x + startx;
            figureHere->vertices[i].y = figureHere->vertices[i-1].y + starty;
            i += 1;
        }
        fgets(line, MAX_WORD - 1, fp);
        nuRead = sscanf(line, "%s", word);
        if (temp == figureHere->countPoints){
            temp = temp * 2;
            figureHere->vertices = realloc(figureHere->vertices, temp * sizeof(struct pointxy));
        }
    }                                          
    figureHere->countPoints = i;                        
}         

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>

void parseFile(FILE * fp, FILE * sketcher); 
void processArgument(char argument[]);
void printOutput();

#define MAX_WORD 256
#define initial_size 17

extern const char argument[];

/* prototypes for non-c99 library functions */
FILE* popen(const char*, const char*);
int pclose(FILE*);
struct pointxy {
    double x;
    double y;
};

struct figure{
      char figureName[MAX_WORD];
    struct pointxy *vertices;
    long int countPoints;
};

*** glibc detected *** ./draw2: realloc(): invalid pointer: 0xbf9c3a28 ***
======= Backtrace: =========
/lib/libc.so.6(realloc+0x3a8)[0x400cb548]
/lib/libc.so.6(realloc+0x3c)[0x400cb1dc]
./draw2[0x8048ab8]
./draw2[0x8048ec1]
./draw2[0x8048f84]
/lib/libc.so.6(__libc_start_main+0xe0)[0x40072390]
./draw2[0x8048891]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 00:16 160237     /home/dsk07/ugrad/pkardash/c201/assignment2/draw2
0804a000-0804b000 rw-p 00002000 00:16 160237     /home/dsk07/ugrad/pkardash/c201/assignment2/draw2
0804b000-0804c000 rw-p 00000000 00:00 0 
09283000-092a4000 rw-p 00000000 00:00 0          [heap]
40000000-4001c000 r-xp 00000000 08:01 94922      /lib/ld-2.7.so
4001c000-4001d000 r--p 0001b000 08:01 94922      /lib/ld-2.7.so
4001d000-4001e000 rw-p 0001c000 08:01 94922      /lib/ld-2.7.so
4001e000-40022000 rw-p 00000000 00:00 0 
40022000-4002c000 r-xp 00000000 08:07 150880     /usr/lib/libgcc_s.so.1
4002c000-4002d000 rw-p 00009000 08:07 150880     /usr/lib/libgcc_s.so.1
40036000-4005a000 r-xp 00000000 08:01 94889      /lib/libm-2.7.so
4005a000-4005b000 r--p 00023000 08:01 94889      /lib/libm-2.7.so
4005b000-4005c000 rw-p 00024000 08:01 94889      /lib/libm-2.7.so
4005c000-401a1000 r-xp 00000000 08:01 94899      /lib/libc-2.7.so
401a1000-401a2000 ---p 00145000 08:01 94899      /lib/libc-2.7.so
401a2000-401a4000 r--p 00145000 08:01 94899      /lib/libc-2.7.so
401a4000-401a5000 rw-p 00147000 08:01 94899      /lib/libc-2.7.so
401a5000-401a9000 rw-p 00000000 00:00 0 
bf9b0000-bf9c5000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
make: *** [run] Aborted

回答1:

glibc is telling you you're passing in an address that couldn't have been returned from malloc/realloc. This is because you're passing in the address of the pointsAndName stack variable. You need to pass in the value, which is what you received from malloc. Also, whenever you call realloc, you should use a temporary variable. That way, if the realloc fails, you still free the original value.

struct figure *tempPtr = realloc(pointsAndname, temp * sizeof(struct figure));
if(tempPtr == NULL)
{
  // Handle allocation error...
  free(pointsAndname);
}
pointsAndname = tempPtr;