【问题标题】:Dynamic memory: malloc and realloc动态内存:malloc 和 realloc
【发布时间】:2011-05-09 16:39:37
【问题描述】:

我是 C 新手,但在使用动态内存时遇到问题。 我 malloc 结构图,然后根据需要重新分配。当我试图调试我的代码时,我注意到在 ddd 的帮助下我覆盖了前一个数字(在我提供的第二块代码中 - 变量的名称是 figureHere)。如果有人能看到我愚蠢错误的原因,请告诉我。

第一个代码块在第二个代码块中调用了一个 void。

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

【问题讨论】:

  • 将来,您应该尝试将示例代码简化到仍然会产生错误的最小量。这甚至可以帮助您自己解决问题。

标签: c malloc realloc


【解决方案1】:

保罗,

您的初始 malloc() 大小为零;您至少需要一个元素才能开始。最重要的是,您正在向后执行此操作。在分配空间来容纳它们之前,您正在尝试将值分配给 figureHere。要么你需要弄清楚你在结构中需要多少个新值,然后调用 malloc(),或者将 realloc() 代码放入 if (strncmp(word, "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;
}

【讨论】:

  • 我可以用 temp = sizeof(struct pointxy) 代替 temp = o 吗?
  • 是的,您需要为至少一个元素分配空间。
【解决方案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-&gt;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);
    }
    /* ... */
}

【讨论】:

  • temp = sizeof(struct figure);
  • @Paul:简洁地说,正如@pmg 建议的(有点间接),您需要在使用之前分配空间。分配零字节是实现定义的行为;你可能会得到一个 NULL 指针,或者你可能会得到一个非空指针,但是由于可用空间为零字节,除了释放它之外,你将无法对它做任何事情。作为一般规则,在提出关于 SO 的问题时,请从代码中消除所有不必要的内容 - 并且显示的代码中有很多不必要的内容。另外,让它可编译 - 你提供的不是。
  • 使用temp = sizeof (struct figure);,您将为 1 个元素分配一个数组:索引为 0 的元素。figureHere-&gt;vertices[1] 仍然不存在
  • @Paul:我们无法确定temp = sizeof(struct figure); 是否合适,因为我们不知道'figureHere-&gt;vertices' 的类型。如果它是指向“struct figure”的指针,那么可能是正确的,但顶点不太可能是完整的图形,因此可能不正确。
  • 我为冗长的代码道歉。我已经添加了 .h 文件,所以很清楚什么是结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 2018-08-29
  • 2021-01-15
  • 1970-01-01
相关资源
最近更新 更多