1

I am making a queue implementation using linked list.. code needs to be compiled without warnings on omega using the command gcc -std=c89 -g –pedantic filename.c. However, I am getting the warnings: assignment from incompatible pointer type [enabled by default] on line numbers(174, 223, 253). Also, I am facing problems in printing the records to the file:

#include <stdio.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

struct student_record
{
        int student_id_;
        int student_age_;
        char first_name_[21];
        char last_name_[21];
};

struct student_record_node
{
        struct student_record* record_;
        struct student_record_node* next_;
}*front,*rear,*temp,*front1;

void enq(struct student_record* sr);
void parseFile(char* filename, struct student_record_node** head);
void printNode(struct student_record_node* node);
struct student_record_node* student_record_allocate();
void student_record_node_deallocate(struct student_record_node* node);
void sortByAge(struct student_record_node** recordsHead);
void sortById(struct student_record_node** front);
void swap(struct student_record_node** node1, struct student_record_node** node2);

int main ( int argc, char *argv[] )
{
        char *filename = argv[1];
        int i;

     /**for(i=0;i<argc;i++)**/
    /**         printf("%d %s ",i,argv[i]);**/


   /**printf( "usage: %s filename", argv[1] );**/
    parseFile(filename,&front);
    printNode(front);

    printf("\n");
    printf("Sorting by age \n");
    sortByAge(&front);
    printNode(front);

    printf("Sorting by id \n");
    sortById(&front);
    printNode(front);

    /**student_record_node_deallocate(front);**/
    getch();
    return 0;
}

void swap(struct student_record_node** node1, struct student_record_node** node2)
{
     struct student_record *s1;
     struct student_record_node *t1 = *node1,*t2=*node2;

     /**s1=(struct node *)malloc(1*sizeof(struct student_record));**/

     s1= t1 -> record_;

     t1->record_= t2->record_;
     t2->record_=s1;

}

void sortByAge(struct student_record_node** front)
{
    int swapped, i;
    struct student_record_node *ptr1;
    struct student_record_node *lptr = NULL;
    struct student_record *s1,*s2;

    /**Checking for empty list**/
    if (ptr1 == NULL)
        return;

    do
    {
        swapped = 0;
        ptr1 = *front;

        while (ptr1->next_ != lptr)
        {
            s1=ptr1->record_;
            s2=ptr1->next_->record_;
            if (s1->student_age_ > s2->student_age_)
            {
                swap(&ptr1, &ptr1->next_);
                swapped = 1;
            }
            ptr1 = ptr1->next_;
        }
        lptr = ptr1;
    }
    while (swapped);



}

void sortById(struct student_record_node** front)
{
    int swapped, i;
    struct student_record_node *ptr1;
    struct student_record_node *lptr = NULL;
    struct student_record *s1,*s2;

    /**Checking for empty list**/
    if (ptr1 == NULL)
        return;

    do
    {
        swapped = 0;
        ptr1 = *front;

        while (ptr1->next_ != lptr)
        {
            s1=ptr1->record_;
            s2=ptr1->next_->record_;
            if (s1->student_id_ > s2->student_id_)
            {
                swap(&ptr1, &ptr1->next_);
                swapped = 1;
            }
            ptr1 = ptr1->next_;
        }
        lptr = ptr1;
    }
    while (swapped);



}



void student_record_node_deallocate(struct student_record_node* node)
{
    front1 = node;
    struct student_record_node* temp;


    if ((front1 == NULL) && (rear == NULL))
    {
        printf("Queue is empty");
        return;
    }
    while (front1 != rear)
    {
        temp =front1;
        front1 = front1->next_;
        free(temp);

    }
    if (front1 == rear)
        {
         free(front1);
        }

    free(node);
    free(temp);

}

struct student_record_node* student_record_allocate()
{
 struct student_record_node* sr;
 sr = (struct node *)malloc(1*sizeof(struct student_record_node));
 return sr;

}

void printNode(struct student_record_node* node)
{
    front1 = front;
    struct student_record* s;


    if ((front1 == NULL) && (rear == NULL))
    {
        printf("Queue is empty");
        return;
    }
    while (front1 != rear)
    {
        s=front1->record_;
         printf("struct student_record_node\n");
         printf("\tstudent firstname %s\n", s->first_name_);
         printf("\tstudent lastname %s\n", s->last_name_);
         printf("\tstudent id %d\n", s->student_id_);
         printf("\tstudent age %d\n\n", s->student_age_);
        front1 = front1->next_;
    }
    if (front1 == rear)
        {
         s=front1->record_;
         printf("struct student_record_node\n");
         printf("\tstudent firstname %s\n", s->first_name_);
         printf("\tstudent lastname %s\n", s->last_name_);
         printf("\tstudent id %d\n", s->student_id_);
         printf("\tstudent age %d\n\n", s->student_age_);
        }
}

void enq(struct student_record* sr)
{

    if (rear == NULL)
    {
        rear = student_record_allocate();//(struct node *)malloc(1*sizeof(struct student_record_node));
        rear->record_ = sr;
        rear->next_ = NULL;
        front = rear;
    }
    else
    {
        temp=(struct node *)malloc(1*sizeof(struct student_record_node));
        rear->next_ = temp;
        temp->record_ = sr;
        temp->next_ = NULL;

        rear = temp;
    }

}
void parseFile(char* filename, struct student_record_node** head)
{
  struct student_record * sr;


  char item[21], status[21];
  int id,age;


  FILE *fp;

  if((fp = fopen(filename, "r+")) == NULL) {
        printf("No such file\n");
        exit(1);
    }

    while (true) {
        int ret = fscanf(fp, "%s %s %d %d", item, status, &id, &age);
        if(ret == 4)
            {
                 /**printf("\n%s \t %s %d %d", item, status, id, age);**/
                  sr = (struct node *)malloc(1*sizeof(struct student_record));
                  strncpy(sr->first_name_, item, 21);
                  /**sr->first_name_ = item;**/
                  strncpy(sr->last_name_,status,21);
                  /**sr->last_name_ = status;**/
                  sr->student_id_=id;
                  sr->student_age_=age;
                  enq(sr);
            }
        else if(errno != 0) {
            perror("scanf:");
            break;
        } else if(ret == EOF) {
            break;
        } else {
            printf("No match.\n");
        }
    }
    printf("\n");
    /*if(feof(fp)) {
        puts("EOF");
    }*/
}

Input file is:

Joe Smith 00001 24
Bob Smith 00002 31
Samantha Smith 00003 30
Christina Smith 00004 17
Steven Smith 00005 20
Jason Smith 00006 3
Patrick Smith 00007 50
Alex Smith    00001 29
  • Where are those lines? It'd be good if you could make a much smaller example showing the problem. – M.M Dec 03 '15 at 05:20
  • This code uses `strncpy` incorrectly in multiple places. You should avoid using this function, and you should use length protection with `%s` in fscanf. – M.M Dec 03 '15 at 05:21
  • The `swap` function isn't implemented properly, this logic wrecks the list. (draw a picture to convince yourself of this) – M.M Dec 03 '15 at 05:25
  • Note that this question is closely related to [Using `gcc -std=c89 -g -pedantic filename.c` — it says "invalid pointer"](https://stackoverflow.com/questions/34055766/using-gcc-std-c89-g-pedantic-filename-cit-says-invalid-pointer) – Jonathan Leffler Dec 03 '15 at 05:33

3 Answers3

0

You should never cast the return of malloc. See this link as to why should not.

So, change the code on line 174.

sr = (struct node *)malloc(1*sizeof(struct student_record_node));

to

sr = malloc(1*sizeof(struct student_record_node));

Repeat this for all the three lines.Other than that the sorting seems to be OK.

To print to a file, you can use the function fprintf(fp,"....") instead of using printf

Community
  • 1
  • 1
Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
  • The `printNode()` function ignores its argument and always dumps the entire list, which is not really a good design. There should be a 'print one node' function, and another function to 'print all nodes in list' which should, in turn, repeatedly call the function that prints one node at a time. I suspect there are other problems — there certainly were in the previous version of this question. – Jonathan Leffler Dec 03 '15 at 05:36
  • can't agree here: Your suggestion makes the warning go away but the code still allocates the wrong number of bytes. It should either be the cast version but with casting to the right type; or (my preference) `sr = malloc( sizeof *sr );` – M.M Dec 03 '15 at 06:11
0

It's (mmm...) because you're assigning an incompatible pointer type.

struct student_record_node* sr;
sr = (struct node *)malloc(1*sizeof(struct student_record_node));

Here you're casting the return value of malloc to "pointer to struct node" and then assigning it to a "pointer to struct student_record_node."

In fact the cast is bad style. Dump it. The return value of malloc is void*, which is compatible with any other pointer. Also, you can use a location as the argument of sizeof, and this has advantages. The 1* is just clutter. So you're left with:

struct student_record_node *sr = malloc(sizeof *sr);

and the error will go away.

Then check for a NULL return value. Get into the habits of real programmers early even if this is a toy.

Also it's not the best idea to be learning c89 syntax, particularly as a new programmer. It actually requires poor style in nontrivial cases. Why do you think gcc requires a flag to force it? I know this is probably beyond your control, but I'd raise it with the teacher.

"Facing problems" is not a question. If you ask for specific help, you'll usually get it here.

Gene
  • 46,253
  • 4
  • 58
  • 96
0

check this line

if (ptr1 == NULL)
    return;

it should be "front" in place of "ptr"

Gtrex
  • 247
  • 1
  • 7