分段错误:将void指针节点添加到列表

时间:2018-04-17 10:40:29

标签: c function-pointers doubly-linked-list

嘿我正在尝试实现一个通用列表迭代器,它可以存储任何类型的元素。它有其他文件来处理正整数类型和字符串类型。但是,我收到一个错误,指出在尝试添加时有分段错误运行测试用例文件时的整数节点。用于添加元素的void指针作为测试输入也包含字符串但是对于这种情况我甚至不能添加整数值来启动。我使用的是linux环境,错误是在运行时指示。这是代码:

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

typedef struct Node {

  char   *value;  // value of thee list item (string)
  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 *elem;
  Node *curr;       // current node in list
  Node *tail;       // last node in list

  ElmCompareFp  cmpElm;
  ElmNewFp  newElm;
  ElmFreeFp freeElm;

  // implemented struct here .. 

} IteratorGRep;


/*


  // functions below .... 
 */


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

  IteratorG it;

  it = malloc(sizeof (struct IteratorGRep));
  assert (it != NULL);
  it->numofit = 0;
  it->head = NULL;
  it->elem=NULL;
  it->tail = NULL;
  it->curr = NULL;
  it->cmpElm=cmpFp;
  it->newElm=newFp;
  it->freeElm=freeFp;
  return it;

    // created list 
}

int  add(IteratorG it, void *vp){

  Node *vep=NULL;
  vep->value=it->newElm(vp);

  if(it==NULL)
  {
    it->head=vep;
    it->curr->prev=NULL;
    it->curr->next=NULL;
    return 1;

  }
  Node *temp=NULL;
  temp=it->next;
  it->next=vep;
  vep->prev=it;
  vep->next=temp;
  temp->prev=vep;

    // Inserts element pointed by 'vp' into list iterator 'it' 
    return 1;
}
int  hasNext(IteratorG it){

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

    // check for any next elements  
    return 0;
}
int  hasPrevious(IteratorG it){

    if(it->curr->prev!=NULL)
    {
      return 1;
    }
    // check for any previous elements 
    return 0;
}
void *next(IteratorG it){
  if(it->curr->next!=NULL)
  {
    it->curr=it->curr->next;
    Node *curre=it->curr;
    return curre;

  }
    // move to next element
    return NULL;
}
void *previous(IteratorG it){

    if(it->curr->prev!=NULL)
    {
      it->curr=it->curr->prev;
      Node *curre=it->curr;
      return curre;

    }

    // moves to previous element
    return NULL;
}
int  del(IteratorG it){
  if(it->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;

  }
     // removes previous element from list 
  if(it->prev==NULL)
  {
    return 0;
  }
}
int  set(IteratorG it, void *vp){
  if(it->prev!=NULL)
  {
  Node *vep=NULL;
  vep->value=it->newElm(vp);
  Node *store_curr=it->curr;
  Node *store_prev=it->curr->prev->prev;

  store_curr->prev=vep;
  vep->next=store_curr;
  store_prev->next=vep;
  vep->prev=store_prev;
  return 1;
  }
    // Replaces previous element with the element (*vp) 
    return 0;
}
IteratorG advance(IteratorG it, int n){


    // Advance by n times and return list with n times of elements
    // To  implement function here and change return value 
    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;    

    // reverses order of list  
}
IteratorG find(IteratorG it, int (*fp) (void *vp) ){

    // finds elements after current position,append to new list
    // To implement function here and change return value 

     return NULL;
}

int distanceFromStart(IteratorG it){

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

  while(c->prev!=NULL)
  {
    c=c->prev;
    count++;
  }
  return count;

     // counts number of nodes from current position to start of list 

}
int distanceToEnd(IteratorG it){

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

  while(cu->next!=NULL)
  {
    cu=cu->next;
    count++;
  }
  return count;
    // counts number of nodes from current position to end of list  

}
void reset(IteratorG it){

  it->curr=it->head;

    // reset to start of list  
    return;
}
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); 

    // remove nodes in it and free memory  

}

这是代码的头文件:

#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

其中一个功能尚未实现,并在代码本身中显示。但我猜这可能不是问题的根源。我认为这里没有正确使用节点。

编辑: 下面是测试用例代码。测试用例代码非常合适:

#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");
}

void test3(){
  printf("\n--====  Test-03       ====------\n");
  IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
  int a[MAXARRAY] = { 04, 54, 15, 12, 34};
  for(int i=0; i<MAXARRAY; i++){
    int result = add(it1 , &a[i]); 
    printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
  }

  reset(it1);
  printf("> it1 (after reset): \n");
  prnIt(it1, prnInt);
  reset(it1);

  IteratorG advIt1 = advance(it1, 4);
  printf("> advance(it1, 4) returns: \n");
  prnIt(advIt1, prnInt);

  IteratorG advIt2 = advance(it1, -3);
  printf("> advance(it1, -3) returns: \n");
  prnIt(advIt2, prnInt);

  printf("> In 'it1', ");
  prnPrev(it1, prnInt);

  freeIt(it1);
  freeIt(advIt1);
  freeIt(advIt2);

  printf("--====  End of Test-03 ====------\n");
}

 void test4(){
  printf("\n--====  Test-04       ====------\n");
  IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
  int a[MAXARRAY] = { 97, 10, 61, 73, 47};
  for(int i=0; i<MAXARRAY; i++){
    int result = add(it1 , &a[i]); 
    printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
  }

  reset(it1);
   printf("> it1 (after reset): \n");
  prnIt(it1, prnInt);
  reset(it1);

  IteratorG findIt1 = find(it1, passMarks);
  printf("> find(it1, passMarks) returns: \n");
  prnIt(findIt1, prnInt);

  printf("> In 'it1', \n");
  prnNext(it1, prnInt);
  prnNext(it1, prnInt);

  int delResult = del(it1);
  printf("\n> del(it1) results in the following and returns %d: \n", delResult );
  reset(it1);
  printf("> it1 (after reset): \n");
  prnIt(it1, prnInt);

  freeIt(it1);
  freeIt(findIt1);

  printf("--====  End of Test-04 ====------\n");
}


void test5(){
  printf("\n--====  Test-05       ====------\n");
  IteratorG it = newIterator(stringCompare, stringNew, stringFree);

  char *strA[MAXARRAY];
  strA[0] = strdup("joe");
  strA[1] = strdup("rita");
  strA[2] = strdup("john");
  strA[3] = strdup("abby"); 
  strA[4] = strdup("peter"); 

  int j;
  for(j=0; j<MAXARRAY; j++){
    int result = add(it , strA[j]); 
    printf("> Inserting %s: %s \n", strA[j], (result==1 ? "Success" : "Failed") );
  }

  prnNext(it, prnStr);
  prnNext(it, prnStr);
  prnPrev(it, prnStr);

  char *newStr1 = "sydney";
  int result2 = set(it, newStr1);
  printf("> Set value: %s ; return val: %d \n", newStr1,  result2 );  

  prnPrev(it, prnStr);

  freeIt(it);
  printf("--====  End of Test-05 ====------\n");
}


void test6(){
  printf("\n--====  Test-06       ====------\n");
  IteratorG it = newIterator(stringCompare, stringNew, stringFree);

  char *strA[MAXARRAY];
  strA[0] = strdup("kylie");
  strA[1] = strdup("lian");
  strA[2] = strdup("john");
  strA[3] = strdup("arnav"); 
  strA[4] = strdup("joe"); 

  int j;
  for(j=0; j<MAXARRAY; j++){
    int result = add(it , strA[j]); 
    printf("> Inserting %s: %s \n", strA[j], (result==1 ? "Success" : "Failed") );
  }

  reset(it);
  printf("> it (after reset): \n");
  prnIt(it, prnStr);
  reset(it);

  IteratorG advIt3 = advance(it, 3);
  printf("> advance(it, 3) returns: \n");
  prnIt(advIt3, prnStr);

  IteratorG advIt4 = advance(it, -2);
  printf("> advance(it, -2) returns: \n");
  prnIt(advIt4, prnStr);

  reset(it);
  printf("> it (after reset): \n");
  prnIt(it, prnStr);
  reset(it);

  IteratorG findit = find(it, prefixJo);
  printf("> find(it, prefixJo) returns: \n");
  prnIt(findit, prnStr);
  printf("\n> In 'it',  \n");
  prnNext(it, prnStr);
  prnNext(it, prnStr);

  freeIt(it);
  freeIt(findit);
  freeIt(advIt3);
  freeIt(advIt4);
  printf("--====  End of Test-06 ====------\n\n");
}



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


  test1();
  //test2();
  //test3();
  //test4();
  //test5();
  //test6();

  return EXIT_SUCCESS;

}

0 个答案:

没有答案