Search code examples
clinked-listdoubly-linked-listprependabstract-data-type

Nodes are inserted but first node entered deleted from the list


Hi am trying to create a generic list iterator that stores elements of integer or string.when i add the nodes to the list and print it as a list,the first node entered is at the last of the list and the last node entered is at the start of the list(like prepending the list)(The code is tested in test case 2 below).However,the issue i am facing is it just "forgets" the first node entered.I even tried to move from the first element of the list and print one by one but it seems like the first node entered is just not there

This is the add function:

int  add(IteratorG it, void *vp){

  Node *temp;
  if ((temp = malloc(sizeof(Node))) == NULL) { 
    return 0; 
  }

  temp->value = it->newElm(vp);


  if(it->curr!=NULL)
  {    

  temp->next=it->curr;
  it->curr->prev=temp;
  it->curr=temp;
  }

  if(it->curr==NULL){

  it->curr=temp;
  it->curr->next=NULL;
  }  

    return 1;
}

I am using a Linux environment and the errors are indicative from the results. Here is the code for the whole program:

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "iteratorG.h"

typedef struct Node {

  void *value;  // value of thee list item
  struct Node *prev;
  // pointer previous node in list
  struct Node *next;
  // pointer to next node in list

  // implemented struct here .. 
} Node;

typedef struct IteratorGRep {

  int  numofit;      // count of items in list
  Node *head;         // first node in list
  Node *curr;       // current node in list
  Node *tail;       // last node in list

  ElmCompareFp  cmpElm;
  ElmNewFp  newElm;
  ElmFreeFp freeElm;

  // implemented struct here .. 

} IteratorGRep;


/*


  //Your  functions below .... 
 */


IteratorG newIterator(ElmCompareFp cmpFp, ElmNewFp newFp, ElmFreeFp freeFp){

    IteratorG newit;


  if ((newit = malloc(sizeof (struct IteratorGRep)))==NULL)
  {
    printf("Error...! \n");

  }

  //assert (newit != NULL);
  newit->numofit = 0;
  newit->head = NULL;
  newit->tail = NULL;
  newit->curr = NULL;
  newit->cmpElm=cmpFp;
  newit->newElm=newFp;
  newit->freeElm=freeFp;
  return newit;

    // implemented function here and changed return value 
}



int  add(IteratorG it, void *vp){

  Node *temp;
  if ((temp = malloc(sizeof(Node))) == NULL) { 
    return 0; 
  }

  temp->value = it->newElm(vp);
  temp->next=NULL;

  if(it->curr==NULL)
  {
    //temp->next=it->curr;
    it->curr=temp;
    it->tail=it->head=it->curr;
  }  

  temp->next=it->curr;
  it->curr->prev=temp;
  it->curr=temp;
  it->head=it->curr;
  //it->curr->prev=temp;
  /*temp->next = it->curr;
  it->curr = temp;
  */
    // add node to list from front 
    return 1;
}
int  hasNext(IteratorG it){

  if(it->curr->next==NULL)
   {
     return 0;
   }


    // check if theres next element/node
    return 1;
}
int  hasPrevious(IteratorG it){

    if(it->curr->prev!=NULL)
    {
      return 1;
    }
    // check if theres previous element/node 
    return 0;
}
void *next(IteratorG it){

  Node *tempo;

  if(it->curr->next==NULL)
  {
    return NULL;
  }
  tempo=it->curr;
  it->curr=it->curr->next;

  // implemented function here  
  return tempo->value;
}
void *previous(IteratorG it){

    Node *tempor;

  tempor=it->curr;
  if(tempor->prev==NULL)
  {
    return NULL;
  }
  tempor=it->curr->prev;

  it->curr=it->curr->prev;
  //tempor=it->curr;

  // move to next node in list  
  return tempor->value;
}
int  del(IteratorG it){
  if(it->curr->prev!=NULL)
  {
    Node *temp_curr=it->curr;
    Node *temp_prev=it->curr->prev->prev;
    temp_curr->prev=temp_prev;
    temp_prev->next=temp_curr;
    return 1;

  }// delete previous node  from list 
  else
    return 0;
}
int  set(IteratorG it, void *vp){
  if(it->curr->prev!=NULL)
  {

  it->curr->prev->value=vp;


  /*  

  Node *wep;
  if ((wep = malloc(sizeof(Node))) == NULL) { 
      return 0; 
  }  


  wep->value=it->newElm(vp);  


  store_next=it->curr;
  store_prev=it->curr->prev->prev;
  store_next->prev=wep;
   wep->next=store_next;

  store_prev->next=wep;
  wep->prev=store_prev;
  */


  return 1;
  }
    // change previous node value with new 
    return 0;
}
IteratorG advance(IteratorG it, int n){



    //To be implemented
    //move forward by n times
    return NULL;
}
void reverse(IteratorG it){
  Node *curr = it->head;
  Node *temp = NULL;
  while(curr != NULL) {
    temp = curr->next;
    curr->next = curr->prev;
    curr->prev = temp;
    curr = temp;
  }
  temp = it->head;
  it->head = it->tail;
  it->tail = temp;// reverse elements of whole list
}
IteratorG find(IteratorG it, int (*fp) (void *vp) ){
    // To be implemented 
    // Find elements of vp in list after current position and put in new list.return the list.
      return NULL;
 }
int distanceFromStart(IteratorG it){

  Node *c=it->curr;
  int count=0;


  while(c->prev!=NULL)
  {
    c=c->prev;
    count++;
  }
  return count;
    // count number of elements from start of list to current position 

}
int distanceToEnd(IteratorG it){

  Node *cu=it->curr;
  int count=0;

  while(cu->next!=NULL)
  {
    cu=cu->next;
    count++;
  }
  return count;
    // count number of elements from end of list to current position
}
void reset(IteratorG it){



  while(it->curr->prev!=NULL)
  {

    it->curr=it->curr->prev;

  }
  return;
    // move current position to start of list

}
 void freeIt(IteratorG it){
  assert(it != NULL);
  Node *curr, *prev;
  curr = it->head;
  while (curr != NULL) {
    prev = curr;
    curr = curr->next;
    free(prev->value);
    free(prev);
  }
  free(it); // free items  

}

This is the header file for the code:

#ifndef LISTITERATORG_H
#define LISTITERATORG_H

#include <stdio.h>

typedef struct IteratorGRep *IteratorG;

typedef int   (*ElmCompareFp)(void const *e1, void const *e2);
typedef void *(*ElmNewFp)(void const *e1);
typedef void  (*ElmFreeFp)(void *e1);


IteratorG newIterator(ElmCompareFp cmpFp, ElmNewFp newFp, ElmFreeFp freeFp);
int  add(IteratorG it, void *vp);
int  hasNext(IteratorG it);
int  hasPrevious(IteratorG it);
void *next(IteratorG it);
void *previous(IteratorG it);
int  del(IteratorG it);
int  set(IteratorG it, void *vp);
IteratorG advance(IteratorG it, int n);
void reverse(IteratorG it);
IteratorG find(IteratorG it, int (*fp) (void *vp) );
int distanceFromStart(IteratorG it);
int distanceToEnd(IteratorG it);
void reset(IteratorG it);
void freeIt(IteratorG it);

#endif

One of the functions have yet to be implemented and is indicated in the code itself. But I guess that might not be the source of issue here. I perceive that the add function is not being utilized properly here.

EDIT: heres the test case code. Theres no errors in the test case code just in the program above only :

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "iteratorG.h"
#include "positiveIntType.h"
#include "stringType.h" 

#define MAXARRAY 5

/* Helper Functions Below */

/* Returns 1 if marks >= 50, 0 otherwise  */
int passMarks(void *marks){
  return (*((int *) marks) >= 50); 

  /* Easy to understand below .. 
     int *ip = (int *) marks;
     if(*ip >= 50) { return 1; }
     else { return 0; } 
  */
}

/* Returns 1 if str starts with "jo" */
int prefixJo(void *str){
  return (strncmp("jo", (char *) str, 2) == 0) ; 
}

/* A function to print a string from a void pointer */
void prnStr(void *vp){
  assert(vp != NULL);
  printf(" %s", (char *) vp );      
}

/* A function to print an integer from a void pointer */
void prnInt(void *vp){
  assert(vp != NULL);
  printf(" %d", *((int *) vp) );    
}

/* Prints previous element using the given function 'fp'
   examples: prnPrev(it1, prnInt); prnPrev(it2, prnStr);
*/
void prnPrev(IteratorG it, void (*fp) (void *p) ){
  void *prevP = previous(it);
  assert(prevP != NULL);
  printf("> Previous value is: "); 
  fp(prevP);
  printf("\n"); 
}

/* Prints next element using the given function 'fp'
   examples:   prnNext(it1, prnInt); prnNext(it2, prnStr);
*/
void prnNext(IteratorG it, void (*fp) (void *p) ){
  void *nextP = next(it);
  assert(nextP != NULL);
  printf("> Next value is: "); 
  fp(nextP);
  printf("\n"); 
}

/* Prints elements of 'it' from current to last position 
   using the given function 'fp'. The current position 
   of 'it' will change to the end of the list.
   examples: prnIt(it1, prnInt); prnIt(it2, prnStr);
*/
void prnIt(IteratorG it, void (*fp) (void *p) ){
  int count = 0;
  while(hasNext(it)){
    void *nextP = next(it); 
    count++;
    if(count > 1) { printf(", "); }
    fp(nextP);      
  }
  printf("\n"); 
}


/* Few Tests Below  */

void test1(){
  printf("\n--====  Test-01       ====------\n");
  IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew,  positiveIntFree);
  int a[MAXARRAY] = { 25, 78, 6, 82 , 11};
  for(int i=0; i<MAXARRAY; i++){
    int result = add(it1 , &a[i]); 
    printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
  }
  freeIt(it1);
  printf("--====  End of Test-01 ====------\n");
}

void test2(){
  printf("\n--====  Test-02       ====------\n");
  IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
  int a[MAXARRAY] = { 72, 14, 62, 8, 93};
  for(int i=0; i<MAXARRAY; i++){
    int result = add(it1 , &a[i]); 
    printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
  }

  prnNext(it1, prnInt);
  prnNext(it1, prnInt);
  prnPrev(it1, prnInt);

  int newVal1 = 55;
  int result1 = set(it1, &newVal1);
  printf("> Set value: %d ; return val: %d \n", newVal1,  result1 );  

  prnPrev(it1, prnInt);

  freeIt(it1);
  printf("--====  End of Test-02 ====------\n");
}



int main(int argc, char *argv[])
{


  test1();
  test2();

  return EXIT_SUCCESS;

}

Solution

  • The node called it->head should be initialzied with the first value as it->curr is assumed to be the first node.Furthermore,to prevent lost of connection with the other nodes,a new node should be initialized with the node stored.So the add function should be like the following:

    int  add(IteratorG it, void *vp){
    
      Node *temp;
      if ((temp = malloc(sizeof(Node))) == NULL) { 
        return 0; 
      }
      Node *tempe;
      if ((temp = malloc(sizeof(Node))) == NULL) { 
        return 0; 
      }
    
      temp->value = it->newElm(vp);
      //temp->next=NULL;
    
      if(it->curr==NULL)
      {
        //temp->next=it->curr;
        it->head=it->tail=temp;
        it->curr=temp;
      }
      else
      {
       tempe=it->curr;
       tempe->prev=temp;
        temp->next=tempe;
        it->curr=tempe;
        it->curr=temp;
        it->head=temp;
    
    
      } 
    
        //it->tail=it->head=it->curr;
        return 1;
      }