0

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.

4
  • why do you do this p_vaild->data =(char)malloc(sizeof(STRINGMAX);? it does not make sense Commented Dec 14, 2014 at 20:11
  • Your code contains internal inconsistencies the compiler should be able to catch much earlier... Commented Dec 14, 2014 at 20:11
  • on a side note you missed an 'fclose(file)' after you have read the file (and if file != NULL) ofcourse. Commented Dec 14, 2014 at 20:23
  • Do not use feof() like this. Instead test result of fgets(), when NULL, exit loop. Commented Dec 14, 2014 at 20:57

3 Answers 3

3

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).

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the help iharob I have amended my program but am unsure of how to malloc the char array. I now have trying it this way : temp->data = (char[STRINGMAX])malloc(sizeof(char)); gives me the error 'cast specifies array type' and trying it any other way gives me the error 'incompatible types when assigning to type char[50] from type char. Thanks again for your help.
You simply don't need to.
Okay thanks, do I need to malloc any of the structure fields then?
It depends on what you want to achieve, please don't ask another question in the comments, ask a new one. For instance, what do you want to store in the ref field? It it is an integer value then it should be declared as int ref and you wont need malloc. If it is an integer array, it is correctly declared and you will need malloc(arraySize * sizeof(int)). Read the malloc manual.
1
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

Comments

-1

From just a quick look, I think your problem may be where you are mallocing in the read_file function. You should havemalloc(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

1 Comment

casting malloc is necessary in C++ because of the way void is treated in C++, but in C it is absolutely not necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.