C -структурен масив, проблеми с free, проблеми с присвояването на стойности в моя структурен масив

Това, което следва, е моята програма. Създавам структура, използвайки malloc за разпределяне на памет, защото искам много голям структурен масив, и след това предавам този структурен масив на функции. Функциите не са важни, защото не мога да изляза от основната програма. Моето объркване е, че моят компилатор (gcc) казва, че each_event е недеклариран, когато се опитвам да го освободя, но никъде другаде. Когато коментирам безплатния израз, той компилира, но след това valgrind казва, че имам невалиден запис с размер 4, когато правя реда each_event[i].timestamp = tim[i]. Горният ред е коментиран, защото valgrind ми каза, че грешката е там (компилирах с gcc -g -O0), въпреки че знаех, че трябва да означава реда по-долу.

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

#define event_length 512
#define bits_n_byte 8
#define timestamp_bytes 8

typedef enum type {
    DATA, CLOCK, EXPECTED, SPILL, ALL
} type;

typedef struct event {
char clocbuffer[event_length*bits_n_byte];
char datbuffer[event_length*bits_n_byte];
char expect[event_length];
char spil[event_length];
char clocerror[event_length*bits_n_byte];
char daterror[event_length*bits_n_byte];
long unsigned int timestamp;
} event;

int i, j, k, l, length, nevents;
char **spil, **expect, **dat, **cloc, **clocerror, **daterror;
long unsigned int *tim;
char library[256];
char *runnum, *clocmode, *datmode;

void GetPiece(char*, type, struct event*);
void FindMode(type);
void ErrorPiece(type);

int main(int argc,char **argv) {
if (argc != 2) {fprintf(stderr, "Format: ./program #_patterns\nTry again.\n");}

for (i=0;i<256;i++) library[i]=i;

FILE *IN = NULL;
char *buffer = NULL;

runnum = (char *) malloc(2);
runnum = strncpy(runnum,argv[1],1);
runnum[1] = '\0';
IN=fopen(argv[1], "r");                 /*Open input file.*/

if (IN)
{
    fseek(IN, 0, SEEK_END);                 /*This finds  */
    length  = ftell(IN);                    /*the length  */
    fseek(IN, 0, SEEK_SET);                 /*of the file.*/
    buffer = malloc(length + 2);            /*for buffer.     */
    fread(buffer, 1, length, IN);
    tim = (long unsigned int *) malloc(length + 2*sizeof(long unsigned int));
    fread(tim, sizeof(long unsigned int), length/sizeof(long unsigned int), IN);
    fclose(IN);

    nevents = length/2056;
    struct event* each_event = (struct event *) malloc(nevents*sizeof(struct event));

    for (i=0; i<length/sizeof(unsigned long int); i+=2056/sizeof(unsigned long int))
    {
    tim[i] = __builtin_bswap32 (tim[i]);
    tim[i]-=0x80000000;
    //if (tim[i]<1200000000 || tim[i]>1300000000) fprintf(stderr, "Check timestamp. Either endianness, size of bytes, or size of long ints are different.");
    each_event[i].timestamp = tim[i];
    }

    clocmode = malloc(nevents);
    datmode = malloc(nevents);

    GetPiece(buffer, DATA, each_event);
    GetPiece(buffer, CLOCK, each_event);
    GetPiece(buffer, EXPECTED, each_event);
    GetPiece(buffer, SPILL, each_event);
    GetPiece(buffer, ALL, each_event);
    FindMode(DATA);
    FindMode(CLOCK);
    ErrorPiece(DATA);
    ErrorPiece(CLOCK);
}
else fprintf(stderr,"Error in file naming/opening.\n");   /*error*/
free (buffer);
free (tim);
free (runnum);
free (clocmode);
free (datmode);
free (each_event);
return 0;}

person jbf81tb    schedule 20.06.2012    source източник


Отговори (1)


Тъй като each_event е деклариран в блока if { ... }, той е извън обхвата, докато се опитате да го free(). Или го освободете в края на if { ... }, или поставете декларацията заедно с другите в началото на main(). Ако направите последното обаче, вероятно ще получите предупреждения, че е възможно да се използва, без да бъде инициализирано, така че първият вариант вероятно е най-добрият.

person twalberg    schedule 20.06.2012
comment
това е точно така. Мислех, че използването на malloc и поставянето на тази памет в купчината е достатъчно, но предполагам, че името на променливата изчезва извън блока. Научавам нещо ново поне веднъж на час! - person jbf81tb; 20.06.2012