AMcoder - javascript, python, java, html, php, sql

Դինամիկ հիշողություն՝ malloc և realloc

Ես նոր եմ C-ում և դժվարանում եմ օգտագործել դինամիկ հիշողությունը: Ես malloc եմ struct գործչի համար և այնուհետև վերաբաշխում եմ ըստ անհրաժեշտության: Երբ ես փորձում էի վրիպազերծել իմ կոդը, ես նկատեցի ddd-ի օգնությամբ, որ ես վերագրում եմ մեկ թվանշանը նախորդի վրա (կոդի երկրորդ մասում, որը ես տրամադրեցի. փոփոխականի անունն է figureHere): Եթե ​​որևէ մեկը կարող է տեսնել իմ հիմար սխալի պատճառը, խնդրում եմ ինձ տեղյակ պահեք:

Կոդի առաջին կտորը երկրորդ մասում բաց է անվանում:

#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;
14.11.2010

  • Ապագայում, դուք պետք է փորձեք պարզեցնել ձեր օրինակի կոդը մինչև ամենափոքր քանակությունը, որը դեռ առաջացնում է ձեր սխալը: Սա նույնիսկ կարող է օգնել ձեզ ինքնուրույն լուծել խնդիրը: 14.11.2010

Պատասխանները:


1

Պողոս,

Ձեր սկզբնական malloc() չափը զրոյական է. սկսելու համար անհրաժեշտ է առնվազն մեկ տարր: Բացի այդ, դուք դա անում եք հետընթաց: Դուք փորձում եք արժեքներ վերագրել figureHere-ին, նախքան դրանք պահելու համար տարածք հատկացնելը: Կամ դուք պետք է պարզեք, թե քանի նոր արժեք է ձեզ անհրաժեշտ կառուցվածքում, այնուհետև զանգահարեք malloc(), կամ տեղադրեք realloc() կոդը if (strncmp(բառ, «draw», MAX_WORD) == 0) բաժնում:

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;
}
14.11.2010
  • temp = o ունենալու փոխարեն կարո՞ղ եմ անել temp = sizeof(struct pointxy): 14.11.2010
  • Այո, դուք պետք է տարածք հատկացնեք առնվազն մեկ տարրի համար: 14.11.2010

  • 2
    void figureFunction (FILE * fp, char line[], char word[], char figureName[], int countNumberoffigures, struct figure *figureHere){
        /* ... */
        int temp = 0;
        /* ... */
        figureHere->vertices = malloc(temp);
    

    ջերմաստիճանը 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;
    

    Ոչ, ոչ, ոչ: figureHere->vertices[1] գոյություն չունի

                figureHere->vertices[i].y = figureHere->vertices[i-1].y + starty;
                i += 1;
            }
            fgets(line, MAX_WORD - 1, fp);
            nuRead = sscanf(line, "%s", word);
        }
        /* ... */
    }
    
    14.11.2010
  • temp = sizeof (կառուցվածքի նկար); 14.11.2010
  • @Paul. հակիրճ, ինչպես @pmg-ը խորհուրդ տվեց (որոշակիորեն անուղղակի), դուք պետք է տարածք հատկացնեք այն օգտագործելուց առաջ: Զրոյական բայթերի հատկացումը իրականացման սահմանված վարքագիծ է. դուք կարող եք ետ ստանալ NULL ցուցիչ, կամ կարող եք ստանալ ոչ զրոյական ցուցիչ, բայց քանի որ կա զրոյական բայթ օգտագործելի տարածք, դուք չեք կարողանա որևէ բան անել դրա հետ, բացի այն ազատելուց: Որպես ընդհանուր կանոն, SO-ի վերաբերյալ հարց տալիս վերացրեք այն ամենը, ինչ անհրաժեշտ չէ կոդից, և ցուցադրված կոդում շատ ավելորդներ կան: Բացի այդ, դարձրեք այն կոմպիլյատիվ. այն, ինչ դուք տրամադրել եք, այդպես չէ: 14.11.2010
  • temp = sizeof (struct figure);-ով դուք զանգված կհատկացնեիք 1 տարրի համար. տարրը 0 ինդեքսում: figureHere->vertices[1] դեռ գոյություն չէր ունենա: 14.11.2010
  • @Paul. մենք իրականում չենք կարող ասել, թե արդյոք temp = sizeof(struct figure);-ը տեղին է, քանի որ մենք չգիտենք, թե որն է «figureHere->vertices»-ի տեսակը: Եթե ​​դա «struct figure»-ի ցուցիչ է, ապա հավանաբար ճիշտ է, բայց քիչ հավանական է, որ գագաթները ամբողջական թվեր են, ուստի, հավանաբար, ճիշտ չէ: 14.11.2010
  • Ներողություն եմ խնդրում երկար կոդի համար։ Ես ավելացրել եմ .h ֆայլը, որպեսզի պարզ լինի, թե որոնք են կառուցվածքները: 14.11.2010
  • Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..