【问题标题】:Unhandled exception in doubly linked lists [closed]双向链表中未处理的异常[关闭]
【发布时间】:2014-07-18 08:58:58
【问题描述】:

我正在尝试通过 std::map 在 C++ 中实现限价订单簿(非常简单),其中键是价格点,值是 PricePoint 对象。

Book 类有两个,bidask(分别)存储买卖。

#include <iostream>
#include <map>
#include <list>
using namespace std;

#define MAX_NUM_ORDERS 512

class Order
{
  public:
  unsigned int id;
  unsigned int price;
  unsigned int volume;
  bool side;
  time_t added;
  time_t executed;
  time_t cancelled;

  Order *next;
  Order *prev;

  Order(unsigned int price, unsigned int volume, bool side)
  {
    this->id = 0;
    this->price = price;
    this->volume = volume;
    this->side = side;
    this->added = 0;
    this->executed = 0;
    this->cancelled = 0;
    this->next = 0;
    this->prev = 0;
  }
};

class PricePoint
{
  public:
    Order *head;
    Order *tail;

    PricePoint(void)
    {
      this->head = 0;
      this->tail = 0;
    }

    void insertAfter(Order *node, Order new_node)
    {
      new_node.next = node->next;

      if(node->next == 0)
      {
        this->tail = &new_node;
      }
      else
      {
        node->next->prev = &new_node;
      }

      node->next = &new_node;
    }

    void insertHead(Order new_node)
    {
      if(this->head == 0)
      {
        this->head = &new_node;
        this->tail = &new_node;
        new_node.prev = 0;
        new_node.next = 0;
      }
      else
      {
        insertAfter(this->tail, new_node);
      }
    }

    void insertTail(Order new_node)
    {
      if (this->tail == 0)
      {
        insertHead(new_node);
      }
      else
      {
        insertAfter(this->tail, new_node);
      }
    }

    unsigned int count(void)
    {
      unsigned int i;
      Order node(0, 0, false);

      while(node.next == 0)
      {
        for(i=0;i<=MAX_NUM_ORDERS;i++)
        {
          // lol
        }
      }

      return i;
    }

    bool empty(void)
    {
      if(this->head == 0)
      {
        return true;
      }
      else
      {
        return false;
      }
    }

    void print(void)
    {
      if(this->empty() == true)
      {
        cout<<"[None]"<<endl;
        return;
      }
      else
      {
        if(this->head != 0)
        {
          unsigned int i;
          Order *node = this->head; // start at the head

          cout<<"id, volume, added"<<endl; // labels

          while(node->next != 0) // while we're not at the end
          {
            cout<<node->id<<", "<<node->volume<<", "<<node->added<<endl;
            node = node->next;
          }
        }
        else // try and catch it again i guess?
        {
          cout<<"[None]"<<endl;
          return;
        }
      }
    }
};

class Book
{
public:
  map<int, PricePoint> bid; // buy-side
  map<int, PricePoint> ask; // sell-side

  int add(Order order)
  {
    order.id = this->bid.size() + this->ask.size() + 1; // this way, buy-side and sell-side orders have unique identifiers

    if(order.side == false) // buy order
    {
      if(this->bid.count(order.price) == 0) // if the price point isn't already there
      {
        PricePoint pp;
        pair<int, PricePoint> new_pp(order.price, pp);
        bid.insert(new_pp); // add the price point (i.e. add an entry to the map)
      }
      else
      {
        this->bid[order.price].insertTail(order); // insert at tail of the doubly linked list
      }
    }
    else if(order.side == true) // sell order
    {
      if(this->bid.count(order.price) == 0)
      {
        PricePoint pp;
        pair<int, PricePoint> new_pp(order.price, pp);
        ask.insert(new_pp); // add the price point (i.e. add an entry to the map)
      }
      {
        this->ask[order.price].insertTail(order); // insert at the tail of the doubly linked list
      }
    }

    return order.id; // the order's id
  }

  int cancel(unsigned int id)
  {

  }

  void print(void)
  {
    unsigned int i = 0;

    cout<<"-------------------------------------BIDS--------------------------------------"<<endl;
    cout<<this->bid.size()<<endl;

    for(i=0;i<this->bid.size();i++)
    {
      cout<<"Orders for $"<<i<<":"<<endl;
      this->bid[i].print();
    }
    i = 0;
    cout<<endl;

    cout<<"-------------------------------------ASKS--------------------------------------"<<endl;

    for(i=0;i<this->ask.size();i++)
    {
      cout<<"Orders for $"<<i<<":"<<endl;
      this->ask[i].print();
    }
    cout<<endl;
  }
};

int main(void)
{
  unsigned int i;
  Book orderbook; // our limit order book

  // some orders
  Order a(4, 33, false);
  Order b(4, 12, true);
  Order c(5, 33, true);

  //add them
  orderbook.add(a);
  orderbook.add(b);
  orderbook.add(c);

  cout<<"Order book is as follows:"<<endl;

  orderbook.print();

  system("pause");

  return 0;
}

我想打印订单簿,但是当我尝试遍历列表时遇到未处理的异常,如下所示:

Unhandled exception at 0x00a418aa in orderbook.exe: 0xC0000005: Access violation reading location 0x00000039.

在调试器中,我看到next 指针最终变成了垃圾,这表明我未能正确初始化,是吗?

此外,程序在异常之前输出垃圾数据(也表示未初始化的指针)。

非常感谢任何帮助,非常感谢。

【问题讨论】:

  • 您的函数将Order 作为一个值,然后您执行this-&gt;tail = &amp;new_node; 之类的操作,这会导致tail 指向函数返回时不再存在的某个位置。将其作为参考传递。
  • 这是方式的许多代码,请将其缩小到相关位。如何找出哪些部分是相关的?在调试器中运行程序,它会停在异常的位置,这意味着你会知道问题出在哪里,并且应该能够找出相关的部分。
  • 你为什么不用std::list?你包括它:#include &lt;list&gt; 但你不使用它。 std::list 是标准的 C++ 链表类,那么你为什么要重新发明轮子呢?你已经在使用std::map,那你为什么不使用std::list??

标签: c++ exception


【解决方案1】:

这些:

void insertAfter(Order *node, Order new_node)
void insertHead(Order new_node)
void insertTail(Order new_node)

插入一个指向局部变量的指针。他们必须拿一个指针:

void insertAfter(Order *node, Order* new_node)
void insertHead(Order* new_node)
void insertTail(Order* new_node)

试试这个(并纠正它,我猜):

#include <iostream>
#include <map>
#include <list>
using namespace std;

#define MAX_NUM_ORDERS 512

class Order
{
  public:
  unsigned int id;
  unsigned int price;
  unsigned int volume;
  bool side;
  time_t added;
  time_t executed;
  time_t cancelled;

  Order *next;
  Order *prev;

  Order(unsigned int price, unsigned int volume, bool side)
  {
    this->id = 0;
    this->price = price;
    this->volume = volume;
    this->side = side;
    this->added = 0;
    this->executed = 0;
    this->cancelled = 0;
    this->next = 0;
    this->prev = 0;
  }
};

class PricePoint
{
  public:
    Order *head;
    Order *tail;

    PricePoint(void)
    {
      this->head = 0;
      this->tail = 0;
    }

    void insertAfter(Order *node, Order* new_node)
    {
      new_node->next = node->next;

      if(node->next == 0)
      {
        this->tail = new_node;
      }
      else
      {
        node->next->prev = new_node;
      }

      node->next = new_node;
    }

    void insertHead(Order* new_node)
    {
      if(this->head == 0)
      {
        this->head = new_node;
        this->tail = new_node;
        new_node->prev = 0;
        new_node->next = 0;
      }
      else
      {
        insertAfter(this->tail, new_node);
      }
    }

    void insertTail(Order* new_node)
    {
      if (this->tail == 0)
      {
        insertHead(new_node);
      }
      else
      {
        insertAfter(this->tail, new_node);
      }
    }

    unsigned int count(void)
    {
      unsigned int i;
      Order node(0, 0, false);

      while(node.next == 0)
      {
        for(i=0;i<=MAX_NUM_ORDERS;i++)
        {
          // lol
        }
      }

      return i;
    }

    bool empty(void)
    {
      if(this->head == 0)
      {
        return true;
      }
      else
      {
        return false;
      }
    }

    void print(void)
    {
      if(this->empty() == true)
      {
        cout<<"[None]"<<endl;
        return;
      }
      else
      {
        if(this->head != 0)
        {
          unsigned int i;
          Order *node = this->head; // start at the head

          cout<<"id, volume, added"<<endl; // labels

          while(node->next != 0) // while we're not at the end
          {
            cout<<node->id<<", "<<node->volume<<", "<<node->added<<endl;
            node = node->next;
          }
        }
        else // try and catch it again i guess?
        {
          cout<<"[None]"<<endl;
          return;
        }
      }
    }
};

class Book
{
public:
  map<int, PricePoint> bid; // buy-side
  map<int, PricePoint> ask; // sell-side

  int add(Order order)
  {
    order.id = this->bid.size() + this->ask.size() + 1; // this way, buy-side and sell-side orders have unique identifiers

    if(order.side == false) // buy order
    {
      if(this->bid.count(order.price) == 0) // if the price point isn't already there
      {
        PricePoint pp;
        pair<int, PricePoint> new_pp(order.price, pp);
        bid.insert(new_pp); // add the price point (i.e. add an entry to the map)
      }
      else
      {
        this->bid[order.price].insertTail(&order); // insert at tail of the doubly linked list
      }
    }
    else if(order.side == true) // sell order
    {
      if(this->bid.count(order.price) == 0)
      {
        PricePoint pp;
        pair<int, PricePoint> new_pp(order.price, pp);
        ask.insert(new_pp); // add the price point (i.e. add an entry to the map)
      }
      {
        this->ask[order.price].insertTail(&order); // insert at the tail of the doubly linked list
      }
    }

    return order.id; // the order's id
  }

  int cancel(unsigned int id)
  {

  }

  void print(void)
  {
    unsigned int i = 0;

    cout<<"-------------------------------------BIDS--------------------------------------"<<endl;
    cout<<this->bid.size()<<endl;

    for(i=0;i<this->bid.size();i++)
    {
      cout<<"Orders for $"<<i<<":"<<endl;
      this->bid[i].print();
    }
    i = 0;
    cout<<endl;

    cout<<"-------------------------------------ASKS--------------------------------------"<< ask.size() <<endl;

    for(i=0;i<this->ask.size();i++)
    {
      cout<<"Orders for $"<<i<<":"<<endl;
      this->ask[i].print();
    }
    cout<<endl;
  }
};

int main(void)
{
  unsigned int i;
  Book orderbook; // our limit order book

  // some orders
  Order a(4, 33, false);
  Order b(4, 12, true);
  Order c(5, 33, true);

  //add them
  orderbook.add(a);
  orderbook.add(b);
  orderbook.add(c);

  cout<<"Order book is as follows:"<<endl;

  orderbook.print();

//  system("pause");

  return 0;
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    相关资源
    最近更新 更多