1

I'm doing this exercise for my base c programming exam and I get this error: "Dereferencing pointer to incomplete type", using code::blocks. Here is my code:

struct listPlot{
char name[25];
char surname[25];
int age;
struct listplot *next;
struct listPlot *prev;
};

struct listPlot *list;

struct listPlot *init(void)
{
    list=malloc(sizeof(list));
    list->next=NULL;
    list->prev=NULL;
    return list;
};

struct listPlot *addElement(struct listPlot *input)
{
    printf("\nNew element, Name:\n");
    gets(input->name);
    printf("\nSurname:\n");
    gets(input->surname);
    printf("\nAge:\n");
    scanf("%d", &input->age);
    struct listPlot *newElement=malloc(sizeof(list));
    *input->next=*newElement; //This is the line where the error occurs
    newElement->next=NULL;
    *newElement->prev=*input;
};

This function addElement should take an listPlot pointer as an input, insert name surname and age, create a new element of the list and return it's pointer. I don't understand what's wrong with it... I apologize for my stupidity. Another question, if i write input->next=newElement; instead of *input->next=*newElement; I get no error but a warning: "assignment from incompatible pointer type [enabled by default]". I'm sorry again for my ineptness, but I must ask you what is the meaning of that and what is the difference between the two lines. Hope you don't mind helping me and thank you in advance.

AstroCB
  • 12,337
  • 20
  • 57
  • 73
  • 1
    …or `sizeof *list`, if you want to use the variable name instead of the type… and you have `struct listplot *next` in your declaration instead of `struct listPlot *next`, which is the reason for your compiler warning (after your error fix, which seems correct to me). Also note that you have to link the previous element to the added element (currently, you are writing to unallocated space instead). And never, ever, use `gets`. – mafso Jun 27 '14 at 15:49
  • Thank you a lot, really. And what an eye you have mafso. Can I ask you why I should never use gets? – user3783681 Jun 27 '14 at 15:54

1 Answers1

1
struct listPlot{
  char name[25];
  char surname[25];
  int age;
  struct listplot *next;
  struct listPlot *prev;
};

You have a typo above. struct listplot *next should be struct listPlot *next (with a capital P). Your compiler doesn't know what a struct listplot is so, naturally, it cannot dereference a pointer to it.


list=malloc(sizeof(list));

This is wrong. The size should be the size of whatever list points to, not the list itself. You should also test the return value of malloc() before using it:

struct listPlot *init(void)
{
  list = malloc (sizeof *list);
  if (list) {
    list->next=NULL;
    list->prev=NULL;
  }
  return list;
}

struct listPlot *addElement(struct listPlot *input)
{
  printf("\nNew element, Name:\n");
  gets(input->name);

gets() is inherently unsafe and should (almost) never be used. If the input is longer than you expect, it will just keep writing outside your buffer. A better alternative is fgets().


  .... 
  struct listPlot *newElement=malloc(sizeof(list));

Wrong size again. Better:

  struct listPlot *newElement = malloc(sizeof *newElement);

Take sizeof the identifier on the left with an asterisk in front of it, and you automatically get the right size (for one element). And the reader doesn't need to lookup what a list is.


  *input->next=*newElement; //This is the line where the error occurs
  newElement->next=NULL;
  *newElement->prev=*input;

These lines should be:

  input->next = newElement;
  newElement->next = NULL;
  newElement->prev = input;
}

Also, you have semicolons at the end of some function definitions. Are those typos? I don't think they will compile.

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42