简体   繁体   中英

Dynamic memory: malloc and realloc

I am new to C and I am having trouble using dynamic memory. I malloc for struct figure and then realloc as needed. As I was trying to debug my code I noticed with the help of ddd that I overwrite one figure over the previous one(in the second chunk of code that I provided - the name of the variable is figureHere). If anyone can see the reson for my stupid mistake please let me know.

First chunk of code calls a void in the second chunk.

#include <assert.h>
#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;                     
    int countNumberoffigures = 0;                                   //accounts to which figure in the array we are on
    printOutput();
    int temp = 0;
    pointsAndname = malloc(temp);
    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){           //1)reads the figure, name and the two starting points
                countNumberoffigures += 1;                      
                assert(pointsAndname != NULL);
                figureFunction(fp,line, word, figureName, countNumberoffigures, pointsAndname + countNumberoffigures - 1);  
                if (temp <= countNumberoffigures){
                    temp += sizeof(struct figure);
                    pointsAndname = realloc(pointsAndname, temp);
                }
            }                                                 
            if(strncmp(word, "printFigure", MAX_WORD)==0){      //4)read the command printFigure, name of the figure
                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
                drawFigure(sketcher, line, countNumberoffigures);
            }
            if(strncmp(word, "translate", MAX_WORD)==0){        //6)read the command translate 
                translate(line, sketcher, countNumberoffigures);
            }
            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);
            }
            if(strncmp(word, "end", MAX_WORD)==0){
                fprintf (sketcher, "end\n");
            }
            if(strncmp(word, "rotate", MAX_WORD)==0){
                rotate(line, sketcher, countNumberoffigures);
            }
        }
    }
}

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){                                                 
            fprintf(stderr, "draw_line error: couldn't close pipe to %s.\n", Exec_c);
            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[], int countNumberoffigures, struct figure *figureHere){
    double startx, starty;
    int temp = 0;
    printf("The line: %s", line);

    figureHere->vertices = malloc(temp);
    sscanf(line, "%s%s%lf%lf%*s", word, figureHere->figureName, &startx, &starty);
    (*(figureHere->vertices)).x = startx;              
    (*(figureHere->vertices)).y = starty;
    printf("I'm in side figureFunction and this is my figureHere->figureName = %s\n\n", figureHere->figureName);
    fgets(line, MAX_WORD - 1, fp);                  
    int nuRead = sscanf(line, "%s", word);              //until the line with End Figure I construct my points of figure.
    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){
            sscanf (line, "%s%lf%lf", word, &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);
    }                                          
    figureHere->countPoints = i;
    if (temp >= figureHere->countPoints){
        temp += sizeof(struct pointxy);
        figureHere->vertices = realloc(figureHere->vertices, temp);
    }                        
}

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.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{
    //struct figure *nextfigure;

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

struct figure *figurehere;

Paul,

Your initial malloc() is zero-sized; you need at least one element to start. On top of that, you are doing this backwards. You are trying to assign values to figureHere before allocating the space to hold them. Either you need to figure out how many new values you need in the structure, then call malloc(), or put the realloc() code into the if (strncmp(word, "draw", MAX_WORD) == 0) section:

if (strncmp(word, "draw", MAX_WORD) == 0){
    temp += sizeof(struct pointxy);
    figureHere->vertices = realloc(figureHere->vertices, temp);
    sscanf (line, "%s%lf%lf", word, &startx, &starty);
    figureHere->vertices[i].x = figureHere->vertices[i-1].x + startx;
    figureHere->vertices[i].y = figureHere->vertices[i-1].y + starty;
    i += 1;
}
void figureFunction (FILE * fp, char line[], char word[], char figureName[], int countNumberoffigures, struct figure *figureHere){
    /* ... */
    int temp = 0;
    /* ... */
    figureHere->vertices = malloc(temp);

temp is 0

    /* ... */
    int nuRead = sscanf(line, "%s", word);              //until the line with End Figure I construct my points of figure.
    int i = 1;                                                     
    while (strncmp(word, "End", MAX_WORD)!=0){ 
        /* ... */
        if (strncmp(word, "draw", MAX_WORD) == 0){
            sscanf (line, "%s%lf%lf", word, &startx, &starty);
            figureHere->vertices[i].x = figureHere->vertices[i-1].x + startx;

No, no, no. figureHere->vertices[1] does not exist

            figureHere->vertices[i].y = figureHere->vertices[i-1].y + starty;
            i += 1;
        }
        fgets(line, MAX_WORD - 1, fp);
        nuRead = sscanf(line, "%s", word);
    }
    /* ... */
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM