0

it's been a long time since I haven't play with pointers and I think im stuck

So I have two class which are nodes and triangles, I am trying to create a square with four triangles (bottom,right,top,left)

A square consists of 5 nodes and a triangle consists of 3 pointers to nodes

Here is my code that I've simplified

#include <iostream>
#include <math.h>
#include <vector>

using namespace std;


class Node {
public:
    float Xx = 0.0; // nodes(i).X
    float Xy = 0.0;
    float xx = Xx; // nodes(i).x
    float xy = Xy;
    vector<float> v;
    float m = 0.0;
    vector<float> f;
    bool fixed = false;

    Node() {
        Xx = 0.0;
        Xy = 0.0;
    }

    Node(float x, float y) {
        Xx = x;
        Xy = y;

        v.push_back(0.0);
        v.push_back(0.0);

        f.push_back(0.0);
        f.push_back(0.0);

        //cout << "the size of f : " << f.size() << endl;

    }


};

    class Triangle {
    public:
        Node *a;
        Node *b;
        Node *c;
        vector<float> stress;

        Triangle(Node *a1, Node *b1, Node *c1) {
            a = a1;
            b = b1;
            c = c1;
            stress.push_back(0.0);
            stress.push_back(0.0);
            stress.push_back(0.0);
            stress.push_back(0.0);
        }
    };


    vector<Node> nodes;
    vector<Triangle> tris;

void createSq(float x, float y, float side) {
    float Ax = x; // -1 
    float Ay = y; // -1
    float hside = side;
    Node A = Node(Ax, Ay);
    Node B = Node(Ax + 2.0 * hside, Ay);
    Node C = Node(Ax, Ay + 2.0* hside);
    Node D = Node(Ax + 2 * hside, Ay + 2 * hside);
    Node E = Node(Ax + hside, Ay + hside);

    Node *pA = &A; // pA is a pointer to the Node A, Triangle containts only the pointers to the nodes
    Node *pB = &B;
    Node *pC = &C;
    Node *pD = &D;
    Node *pE = &E;

    //cout << " A: " << A << " B : " << B << endl;

    nodes.push_back(A);
    nodes.push_back(B);
    nodes.push_back(C);
    nodes.push_back(D);
    nodes.push_back(E);

    tris.push_back(Triangle(pA, pC, pE));
    tris.push_back(Triangle(pA, pB, pE));
    tris.push_back(Triangle(pB, pD, pE));
    tris.push_back(Triangle(pC, pD, pE));
}


int main(int argc, char* argv[]) {
    float nTiles = 1;
    float hside = 1 / nTiles;

    createSq(-1.0, -1.0, hside);

    for (int i = 0; i < nodes.size(); i++) {
        cout << "the value of Xx: " << nodes[i].Xx << " and the Xy: " << nodes[i].Xy << endl;
    }

    cout << " the value of Xx of tris : " << tris[0].a->Xx << endl;

    while (1) {

    }
    return 0;

}

After the code is executed, it results like this :

Result

As you can see, if I try to access the value of Xx from the nodes vector, it will display the number correctly. However if I access it from the tris vector, it outputs a really huge number

Anyone know what is the problem here ? it seems that I am missing something

UPDATE :

Based from the comments, I changed my code a little bit

    tris.push_back(Triangle(&nodes[nodes.size() - 5], &nodes[nodes.size() - 3], &nodes[nodes.size() - 1]));
    tris.push_back(Triangle(&nodes[nodes.size() - 5], &nodes[nodes.size() - 4], &nodes[nodes.size() - 1]));
    tris.push_back(Triangle(&nodes[nodes.size() - 4], &nodes[nodes.size() - 2], &nodes[nodes.size() - 1]));
    tris.push_back(Triangle(&nodes[nodes.size() - 3], &nodes[nodes.size() - 2], &nodes[nodes.size() - 1]));

and now it works, however, I will try to change this using list because I heard that it is risky to use vectors

Aldo aldo
  • 382
  • 1
  • 2
  • 10
  • Possible duplicate of [Pointer to local variable](http://stackoverflow.com/questions/4570366/pointer-to-local-variable) – Ken Y-N Dec 05 '16 at 04:02
  • 3
    Your vectors don't contain pointers, they contain objects, and when you add an object to a vector it makes a copy. The objects can also move in memory when the vector is resized. What you're trying to do won't work. – Retired Ninja Dec 05 '16 at 04:02
  • Any ideas on the alternate methods of this ? So does this mean I can't use the triangle object in order to create the pointers ? – Aldo aldo Dec 05 '16 at 04:07
  • Also, `Node A`, `Node B`, etc. are local variables. Their lifetimes do not go beyond that function. Thus storing pointers to them in your `Triangle` objects will not work, as the pointers will point to junk as soon as that function returns. – PaulMcKenzie Dec 05 '16 at 04:08
  • Those pointers will be invalid at the end of the function, but copies of `A`, `B`, `C`, etc... will live on in `nodes`. Pointers to them are extremely risky (invalidated if `nodes` gets resized, copied and destroyed, few other cases), but you may be able to make use of the indexes of the copies in `nodes`. – user4581301 Dec 05 '16 at 04:14
  • If you want persistent pointers, use a `std::list` instead of `std::vector`, and have pointers to the items within the `std::list`. The only way to get into trouble is if the `list` itself gets destroyed, or the item you're pointing to is removed from the list. – PaulMcKenzie Dec 05 '16 at 04:16
  • Hello Paul, I tried to use list, but I just remembered that you can only access the front and back of the list at a time. This will not work later on with my implementation, do you think its okay for me if I initialize the vector with a number first so that it won't be resized later ? – Aldo aldo Dec 05 '16 at 04:30
  • @Aldoaldo -- You can use the `vector::reserve()` function to get the memory up front, thus no reallocation will be done. But be careful -- 1) `reserve()` is **not** `resize()`. All `reserve()` does is allocate the memory, but does not create any objects (your vector will still be empty). Also 2), if your program does go over the `reserve()`, you are risking a reallocation occurring. So basically you have to ensure what you're reserving is enough to never need a reallocation. – PaulMcKenzie Dec 05 '16 at 20:02

0 Answers0