将地址存储到堆栈中的已分配对象

时间:2016-03-24 10:52:00

标签: c++ pointers vector

我在向量中存储指向堆栈分配对象的地址时遇到问题。不知何故,指针似乎以我不理解的方式相互覆盖。

在我的主要内容中,我想从文件中读取,创建节点(已分配堆栈)并将它们放在向量中。稍后我继续从文件中读取以在节点之间创建连接(边缘),因此堆栈分配Edge对象并尝试将地址存储到相应节点中的这些地址(节点包含向量)。输入文件的格式为index_1 a,index_2,b,capacity c,这意味着要创建一个Edge从a到b,反之亦然,其容量为c。

每次我向节点添加一个Edge(vector :: push_back())时,Node中的整个向量都被设置为相同的指针(而不是按照预期附加另一个指针)。将3个边添加到同一节点后的示例输出:

#0 named: ORIGINS connected to: 
#1 named: 2, capacity: -1, flow: 0

#0 named: ORIGINS connected to: 
#17 named: 3W, capacity: -1, flow: 0
#17 named: 3W, capacity: -1, flow: 0

#0 named: ORIGINS connected to: 
#16 named: 3E, capacity: -1, flow: 0
#16 named: 3E, capacity: -1, flow: 0
#16 named: 3E, capacity: -1, flow: 0

如果有任何测试或打印件,请原谅我的代码:

主要:

#include <iostream>
#include <vector>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <algorithm>
#include <map>
#include <sstream>
#include "Edge.h"
#include "Node.h"
#include <memory>

using namespace std;

ostream& operator<<(ostream& os, const Node& obj) {
    os << "#" << obj.index << " named: " << obj.name << " connected to: " << endl;
    for (size_t i = 0; i < obj.edges.size(); ++i) {
        Edge* e = obj.edges[i];
        os << "#" << e->getEndNode()->getIndex() << " named: " << e->getEndNode()->getName() << ", capacity: " << e->getCapacity() << ", flow: " << e->getFlow() << endl;
    }
    return os;
}

int main() {
    string fileName = "rail.txt";

    //open file
    ifstream infile(fileName.c_str());

    //initialize variables
    string line;
    vector<Node> graph;

    int n;
    getline(infile, line);
    n = atoi(line.c_str());
    //read n nodes
    for (int i = 0; i < n; ++i) {
        if (getline(infile, line)) {
            Node node(line, i);
            graph.push_back(node);
        } else {
            cout << "Error in parsing nodes" << endl;
            return 1;
        }
    }

    int m;
    getline(infile, line);
    m = atoi(line.c_str());
    //read m edges
    for (int i = 0; i < m; ++i) {
        if (getline(infile, line)) {
            istringstream iss(line);
            int a, b, c;

            iss >> a >> b >> c;
            Edge e1(&graph[b], c, 0);
            Edge e2(&graph[a], c, 0);
            graph[a].addEdge(&e1);
            graph[b].addEdge(&e2);
            cout << graph[a] << endl;
        } else {
            cout << "Error in parsing edges" << endl;
            return 1;
        }
    }

    /*for (auto e : graph[0].getEdges()) {
        cout << e->getEndNode()->getName() << endl;
    }*/


    return 0;
}

Edge.cpp:

#include "Edge.h"

Edge::Edge() : endNode(nullptr), capacity(0), flow(0) {};
Edge::Edge(Node* n, int c, int f) : endNode(n), capacity(c), flow(f) {};
Edge::Edge(const Edge& other) {
    endNode = other.endNode;
    capacity = other.capacity;
    flow = other.flow;
};

bool Edge::pushFlow(int f) {
    if (flow + f <= capacity) {
        flow += f;
        return true;
    } else {
        return false;
    }
}

bool Edge::popFlow(int f) {
    if (flow - f >= 0) {
        flow -= f;
        return true;
    } else {
        return false;
    }
}

Node* Edge::getEndNode() {
    return endNode;
}

int Edge::getCapacity() {
    return capacity;
}

int Edge::getFlow() {
    return flow;
}

Node.cpp:

#include "Node.h"
#include <iostream>
Node::Node() : name(""), index(-1) {};
Node::Node(std::string n, int i) : name(n), index(i) {};
Node::Node(const Node& other) : name(other.name), index(other.index), edges(other.edges) {};

void Node::addEdge(Edge* e) {
    edges.push_back(e);
}

std::vector<Edge*> Node::getEdges() {
    return edges;
}

Node& Node::operator=(const Node& rhs) {
    if (this == &rhs) return *this;
    name = rhs.name;
    index = rhs.index;
    edges = rhs.edges;
    return *this;
}

std::string Node::getName() {
    return name;
}

int Node::getIndex() {
    return index;
}

感谢您的帮助或指针(他)!

1 个答案:

答案 0 :(得分:3)

一旦执行离开范围,声明了非static变量,该变量就不再存在,指向它的指针变为悬空指针

悬空指针无效。即使只是检查该值也可能导致硬件陷阱。因此,任何使用它都是未定义的行为。

所以这就是你所拥有的,因为你做了像

这样的事情
graph[a].addEdge(&e1);

在循环中e1是循环体中声明的变量。