与C ++中另一个LinkedList嵌套的LinkedList整数的回调函数问题

时间:2018-03-10 00:56:52

标签: c++ arduino

我在嵌套在另一个LinkedList中的LinkedList的整数上迭代和应用回调函数时遇到了麻烦。调用board.forEach(printBoard);,我没有获得76543217654321的预期输出,而是没有输入。由于A.forEach(printByte);确实返回7654321,我很难搞清楚问题。如果你知道我的代码有什么问题,请告诉我。感谢。

template <class T> 
class LinkedList {
  struct Node {
      T x;
      Node *next;
  };
  private:
    Node *head;
  public:
    LinkedList(){
        head = NULL;
    }

    ~LinkedList(){
        Node *next = head;

        while(next) {  
            Node *deleteMe = next;
            next = next->next;
            delete deleteMe;
        }
    }

    // prepend a new value to the beginning of the list
    void add(T val){
        Node *n = new Node();
        n->x = val;
        n->next = head;
        head = n;
    }

    void forEach(void (*callback)(T)) {
      Node *n = head;
      while (n != NULL) {
        (*callback)(n->x);
        n = n->next;
      }
    }
};

void printInt(int x) {
  Serial.print(x);
}

void printBoard(LinkedList<int> x) {
  x.forEach(printInt);
}

void setup() {
  Serial.begin(9600); 

  LinkedList<int> A;
  A.add(1);
  A.add(2);
  A.add(3);
  A.add(4);
  A.add(5);
  A.add(6);
  A.add(7);
  A.forEach(printInt); // returns 7654321

  LinkedList<LinkedList<int>> board;
  board.add(A);
  board.add(A);
  board.forEach(printBoard); // returns nothing
}

1 个答案:

答案 0 :(得分:0)

我认为代码存在一些内存问题。节点的地址(指针)是重复的(双重自由问题)。如果要复制结构,则需要新的内存分配和链接列表节点的重新寻址。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

using namespace std ;

template <class T> 
class LinkedList {
  struct Node {
      T *x;
      Node *next;
  };
  private:
    Node *head;
  public:
    LinkedList(){
        printf("constructor:%p\n", this) ;
        head = NULL;
    }

    ~LinkedList(){
        printf("destructor:%p\n", this) ;
        Node *next = head;
        while(next) {  
            Node *deleteMe = next;
            next = next->next;
            printf("delete node:%p\n", deleteMe) ;
            delete deleteMe->x ;    // x
            delete deleteMe;
        }
    }

    LinkedList* Dup() {
        LinkedList *newList = new LinkedList<T>() ;
        Node *n = head ;
        while (n != NULL) {
            T *newx = new T(); 
            *newx=*(n->x) ;
//          newList->addTail(n->x) ;
            newList->addTail(newx) ;
            n = n->next;
        }
        return newList ;
    }

    // prepend a new value to the beginning of the list
    // val : caller must allocate memory.
    void add(T *val){
        Node *n = new Node();
        printf(" addhead: new alloc node %p\n", n) ;
//      T *newval = new T();
//      *newval = *val ;
//        n->x = newval;
        n->x = val ;
        n->next = head;
        head = n;
    }

    // add to end
    // val : caller must allocate memory.
    void addTail(T *val) {
        Node *n = new Node();
        Node *l = head ;

        printf(" addtail: new alloc node %p\n", n) ;
//      T *newval = new T();
//      *newval = *val ;
//        n->x = newval;
        n->x = val ;
        n->next = NULL ;
        if ( l==NULL ) {
            head = n ;
            return ;
        }
        while(l->next!=NULL) {
            l = l->next ;
        }
        l->next = n ;
    }

    void forEach(void (*callback)(T*)) {
      Node *n = head;
      while (n != NULL) {
        (*callback)(n->x);
        n = n->next;
      }
      printf("\n");
    }
};

void printInt(int *x) {
//  Serial.print(x);
    printf("%d ", *x) ;
}

void printBoard(LinkedList<int> *x) {
  x->forEach(printInt);
}

int main() {
  //Serial.begin(9600); 

  printf("make A\n") ;
  int avail_Afree=0 ;

#if 0
    // use stack memory
  LinkedList<int> A;
  LinkedList<int> *pA=&A;
#else
    // use heap
  LinkedList<int> *pA = new LinkedList<int>();
  avail_Afree=1 ;
#endif
  int val=0 ;

  for (int i=1; i<=7; i++) {
    printf("add node:%d\n", i) ;
//    val=i ;
    int *pval = new int() ;
    *pval = i ;
//    pA->add(&val);
    pA->add(pval);
  }
  pA->forEach(printInt);


    // prepare copied data.
  LinkedList<int> *pA2, *pA3 ;
printf("make A2\n") ;
  pA2 = pA->Dup() ;
  pA2->forEach(printInt) ;

printf("make A3\n") ;
  pA3 = pA->Dup() ;
  pA3->forEach(printInt) ;


    // make board
  LinkedList<LinkedList<int> > *pBoard;
  printf("make Board\n") ;
  pBoard = new LinkedList<LinkedList<int> > () ;

    printf("  Board add: A2\n") ;
  pBoard->add(pA2);

    printf("  Board add: A3\n") ;
  pBoard->add(pA3);

    printf(" print Board\n") ;
  pBoard->forEach(printBoard); // returns nothing

  if ( avail_Afree ) {
    printf("delete pA:%p\n", pA) ;
    delete pA ;
  }

/* 
  printf("delete pA2:%p\n", pA2) ;
  delete pA2 ;
  printf("delete pA3:%p\n", pA3) ;
  delete pA3 ;
  // pBoard will free A2,A3.
*/
  printf("delete pBoard:%p\n", pBoard) ;
  delete pBoard ;

  return 0 ;
}

输出就是这个

make A
constructor:0x7fb8f8d00000
add node:1
 addhead: new alloc node 0x7fb8f8d00020
add node:2
 addhead: new alloc node 0x7fb8f8d00040
add node:3
 addhead: new alloc node 0x7fb8f8d00060
add node:4
 addhead: new alloc node 0x7fb8f8d00080
add node:5
 addhead: new alloc node 0x7fb8f8d000a0
add node:6
 addhead: new alloc node 0x7fb8f8d000c0
add node:7
 addhead: new alloc node 0x7fb8f8d000e0
7 6 5 4 3 2 1 
make A2
constructor:0x7fb8f8d000f0
 addtail: new alloc node 0x7fb8f8d00110
 addtail: new alloc node 0x7fb8f8d00130
 addtail: new alloc node 0x7fb8f8d00150
 addtail: new alloc node 0x7fb8f8d00170
 addtail: new alloc node 0x7fb8f8d00190
 addtail: new alloc node 0x7fb8f8d001b0
 addtail: new alloc node 0x7fb8f8d001d0
7 6 5 4 3 2 1 
make A3
constructor:0x7fb8f8d001e0
 addtail: new alloc node 0x7fb8f8d00200
 addtail: new alloc node 0x7fb8f8d00220
 addtail: new alloc node 0x7fb8f8d00240
 addtail: new alloc node 0x7fb8f8d00260
 addtail: new alloc node 0x7fb8f8d00280
 addtail: new alloc node 0x7fb8f8d002a0
 addtail: new alloc node 0x7fb8f8d002c0
7 6 5 4 3 2 1 
make Board
constructor:0x7fb8f8d002d0
  Board add: A2
 addhead: new alloc node 0x7fb8f8d002e0
  Board add: A3
 addhead: new alloc node 0x7fb8f8d002f0
 print Board
7 6 5 4 3 2 1 
7 6 5 4 3 2 1 

delete pA:0x7fb8f8d00000
destructor:0x7fb8f8d00000
delete node:0x7fb8f8d000e0
delete node:0x7fb8f8d000c0
delete node:0x7fb8f8d000a0
delete node:0x7fb8f8d00080
delete node:0x7fb8f8d00060
delete node:0x7fb8f8d00040
delete node:0x7fb8f8d00020
delete pBoard:0x7fb8f8d002d0
destructor:0x7fb8f8d002d0
delete node:0x7fb8f8d002f0
destructor:0x7fb8f8d001e0
delete node:0x7fb8f8d00200
delete node:0x7fb8f8d00220
delete node:0x7fb8f8d00240
delete node:0x7fb8f8d00260
delete node:0x7fb8f8d00280
delete node:0x7fb8f8d002a0
delete node:0x7fb8f8d002c0
delete node:0x7fb8f8d002e0
destructor:0x7fb8f8d000f0
delete node:0x7fb8f8d00110
delete node:0x7fb8f8d00130
delete node:0x7fb8f8d00150
delete node:0x7fb8f8d00170
delete node:0x7fb8f8d00190
delete node:0x7fb8f8d001b0
delete node:0x7fb8f8d001d0