设置不存储指针集合

时间:2014-06-19 14:10:31

标签: c++ pointers struct

我有一个初始化的struct(nodeT)映射,称为map_nodes,其键是一个字符串名称,它是一个城市名称,值是一对坐标(城市所在的位置)。

我正在尝试在这个结构中存储一个集合,这将收集支出的数量" arcs"对于每个城市。

这些是我的结构:

struct arcT {
int distance;
nodeT *start, *end;

};

struct nodeT {
string name; 
coordT coordinates;
Set<arcT*> outgoing; 
};

我正在尝试,在一个逐行读取数据文件的大型函数中,也将每个完成的arcT添加到节点中的集合,该节点也是特定结构的开始&#34;开始&#34 ;节点。

但是,它没有正确存储。它添加了一个指向集合的指针,但是当我在程序结束时检查给定节点的集合值时,它是空的。这是添加到给定节点的传出向量的函数(除了用于创建arcT结构的一些其他操作):

void addArc(Map<nodeT> & map_nodes, string line) {

Scanner scanner;
scanner.setSpaceOption(Scanner::IgnoreSpaces);
scanner.setInput(line);

string start = ""; string end = ""; int distance = 0;

while (scanner.hasMoreTokens()) {

    arcT *arc = new arcT;

    start = scanner.nextToken();
    nodeT *temp = new nodeT; 
    *temp = map_nodes.getValue(start);
    arc->start = temp;

    end = scanner.nextToken();
    nodeT *temp_next = new nodeT;
    *temp_next = map_nodes.getValue(end);
    arc->end = temp_next;

    distance = StringToInteger(scanner.nextToken());
    arc->distance = distance;

    nodeT *temp_last = new nodeT;
    *temp_last = map_nodes.getValue(start);
    temp_last->outgoing.add(arc);
    cout << "The city is: " << start << " and the size: " << temp_last->outgoing.size() << endl;
}
}

函数原型是:void addNode(Map&amp; map_nodes,string line);

为什么不将这些弧存储在相应的起始节点的集合中?当我尝试为特定节点获取集合的值时,大小始终为0.

1 个答案:

答案 0 :(得分:0)

首先,addArc()

中有三次内存泄漏
void addArc(Map<nodeT> & map_nodes, string line) {
  Scanner scanner;
  scanner.setSpaceOption(Scanner::IgnoreSpaces);
  scanner.setInput(line);
  string start = ""; string end = ""; int distance = 0;

  while (scanner.hasMoreTokens()) {
    arcT *arc = new arcT;
    start = scanner.nextToken();
    nodeT *temp = new nodeT; 
    // MEMORY LEAK
    *temp = map_nodes.getValue(start);
    arc->start = temp;
    end = scanner.nextToken();
    nodeT *temp_next = new nodeT;
    // MEMORY LEAK
    *temp_next = map_nodes.getValue(end);
    arc->end = temp_next;
    distance = StringToInteger(scanner.nextToken());
    arc->distance = distance;

    nodeT *temp_last = new nodeT;
    // MEMORY LEAK
    *temp_last = map_nodes.getValue(start);
    temp_last->outgoing.add(arc);
    cout << "The city is: " << start << " and the size: " << temp_last->outgoing.size() << endl;
  }
}

我已经删除了这些错误并清理了一些代码(如果有人可以验证减少的代码是否正确减少了会很感激!):

void addArc(Map<nodeT> & map_nodes, string line) {
  Scanner scanner;
  scanner.setSpaceOption(Scanner::IgnoreSpaces);
  scanner.setInput(line);
  while (scanner.hasMoreTokens()) {
    arcT *arc = new arcT;
    string start = scanner.nextToken();
    arc->start = &map_nodes.getValue(start);
    arc->end = &map_nodes.getValue(scanner.nextToken());
    arc->distance = StringToInteger(scanner.nextToken());
    arc->start->outgoing.add(arc);
    cout << "The city is: " << start << " and the size: " << arc->start->outgoing.size() << endl;
  }
}

据我所知,如果Set按预期工作,这应该可行。因此,我的结论是Set没有像人们期望的那样发挥作用。

此外,我们看不到Map是什么,也不知道map_nodes.getValue(start)的值最初填充的位置。因此,我们不知道返回的是什么以及您尝试修改的指针。 Map是否进行边界检查?您确定要处理的是实际有效的对象吗?

内存泄漏

A* a = new A();
a = someOtherPtr;

当你使用new时,你从堆(而不是堆栈)分配内存。这永远不会自动清理,程序员应该在某个时候调用delete a。在a = someOtherPointer之后,您无法delete在创建heap时从new A()分配的内存。如果您之后调用delete a,则只会删除someOtherPointer指向的内容,而不会删除调用new时使用的内存。

这是您应该使用C ++教科书进行修改的内容。