简体   繁体   中英

Malloc an array of structs.

I am still learning C and have run into some trouble while trying to malloc structures. I have the following structure:

struct data {
int *ref; 
int *port;
char data[MAX_STRING];
}temp, valid, invalid;

I intend on using the 'temp' struct to store input data before it is validated, then dependent on the outcome of the validation the struct will be copied to a member of either the valid or invalid array of structs.

int main(){
   char inputfile[100];
   FILE *file; = fopen("file.txt" , "r");

   if (file != NULL){
      read_file (file);
   }

   else{
    // Some code here..
   }

   return 0;
}  

void read_file(FILE *file)
{

char buf[1024];

   while(!feof (file))
   {
       struct temp *p_temp = malloc(sizeof(temp));

       p_temp->ref = malloc(sizeof(int));         <<<<<<< 'dereferencing pointer to incomplete type'
       p_temp->port = malloc(sizeof(int));        <<<<<<< 'dereferencing pointer to incomplete type'
       p_temp->data = malloc(sizeof(MAX_STRING)); <<<<<<< 'dereferencing pointer to incomplete type'

       fgets(buf, sizeof buf, file); 

       sscanf(buffer, "%d.%d.%s", p_temp->ref, p_temp->port,  p_temp->data);

       validate();

     }
}

Have I gone about using malloc the correct way with the temporary structure? I am getting the error 'dereferencing to incomplete type'

How would I then go about creating an array of valid and invalid structures that are malloced? Would I create a function such as:

vaild* vaild_record(){

struct vaild *p_vaild = malloc(sizeof(vaild));
if ( p_vaild == NULL)

{
    // some code here
}

p_vaild->ref= malloc(sizeof(int));
p_vaild->port = malloc(sizeof(int));
p_vaild->data =(char)malloc(sizeof(STRINGMAX);

if ( p_vaild->ref == NULL || p_vaild->port == NULL || p_vaild->data == NULL)
{
   // some code here
}

return 0;
}

Im a bit confused about the whole thing. Any clarity would be great thanks.

Your problem is the way you declared the struct it should be

struct data 
{
    int *ref; 
    int *port;
    char data[MAX_STRING];
};

and then you do

struct data *p_valid;
p_valid = malloc(sizeof(struct data));

another thing is

p_valid->data = malloc(sizeof(STRINGMAX));

is wrong because data is not a pointer. And sizeof(STRINGMAX) is wrong too, since STRINGMAX seems to be a macro and hence it will expand to it's value say if you have #define STRINGMAX 4 then it would expand to sizeof(4) .

Your definition of the struct:

struct data {
    int *ref; 
    int *port;
    char data[MAX_STRING];
}temp, valid, invalid;

should be more like this:

struct data 
{
    int *ref; 
    int *port;
    char data[MAX_STRING];
};

then define the arrays similar to this:

struct data temp;

struct data* valid = NULL;
struct data* invalid = NULL;
int currentValidSize = 0;
int currentInvalidSize = 0;
struct data * validTemp = NULL;
struct data * invalidTemp = NULL;

then, each time the code needs room for (another) instance of a struct

struct data *validTemp = realloc(valid, (currentValidSize+1)* sizeof(data) );
if( NULL == validTemp )
{ // realloc failed
    perrof( "realloc failed" );

    // free everything, close files, etc here probably be writing a sub function
    // and calling it here.
    // a sub function that: 
    // that walks the valid and invalid arrays, 
    // first free'ing any malloc'd fields
    // then finally free'ing the whole array

    exit( EXIT_FAILURE );
}

// implied else, realloc successful

// update array size counter
currentValidSize++;

// update ptr to valid array of structs
valid = validTemp;
validTemp = NULL;

similar for adding an entry to the invalid array of structs

then update the valid array of structs from temp as:
(note the '-1' in the offset into valid[])

memcpy( &valid[currentValidSize-1], &temp, sizeof data );
// Note you will also have to perform a 'deep' copy of any areas 
// that were malloc'd within the 'temp' struct

From just a quick look, I think your problem may be where you are mallocing in the read_file function. You should have malloc(sizeof(struct temp)) .

Also casting the malloc wouldn't hurt.

Also there is no need for the temp, valid, invalid at the end of the struct, just use struct data

Hope this helps

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