1

I am currently programming a template matrix. It contains a vector<vector<T>> called mat and cols and rows vals that contain the number of rows and columns. I tried to build an iterator, and found out that I cannot build an iterator function for vector of vector. since the rest of my code was already written, i added a matrixToVector function which turn my vector<vector<T>> to vector<T> (I know it's not the best option, but it's just for a college exercise). On my windows laptop in tuns great, but on the linux computer labs the first two number of the iterator are always a very large random number and then 0 and then the rest of the numbers are fine. Here is the code:

    /**
     * turns the 2d mat vecor to 1d vector.
     */
    vector<T> matrixToVector()
    {
        vector<T> v;
        for(unsigned int i = 0 ; i < rowsNum; i++)
        {
            for(unsigned int j = 0; j < colsNum; j++)
            {
                v.push_back(mat[i][j]);
            }
        }
        return v;

    }

    /**
     * iterator
     */
    typedef typename std::vector<T>::const_iterator const_iterator;


    /**
     * return the end of the iterator.
     */
    const_iterator end()
    {
        return matrixToVector().end();
    }

    /**
     * return the begining of the iterator.
     */
    const_iterator begin()
    {
        return matrixToVector().begin();
    }

I don't have a clue what's wrong. What should I do?

EDIT: When I print the matrix with the regular printing function, it's works great on Linux and Windows.

  • 2
    You have undefined behaviour. The vector that `matrixToVector` creates goes out of scope and the iterator that `begin` returns will be pointing to a destructed object. – Simon Gibbons Nov 18 '15 at 19:48
  • @lurker printing with the regular printing function that prints the matrix works great on linux as well. – One_Curious_User Nov 19 '15 at 05:53
  • @SimonGibbons in this case, why I successfully print the whole matrix content except for the first two elements? – One_Curious_User Nov 19 '15 at 05:55

1 Answers1

7
const_iterator begin()
    {
        return matrixToVector().begin();
    }

you return reference to object on stack, result of matrixToVector() create temporary object, that will be destroyed after return from begin

fghj
  • 8,898
  • 4
  • 28
  • 56
  • "You return a reference to object on stack," <- not exactly. What is returned is indeed an iterator *by value*. The problem isn't that a reference to temporary is returned, but that an invalid iterator is returned. – Edward Strange Nov 18 '15 at 20:00
  • @CrazyEddie Same thing. The iterator is invalid because it's a reference to a temporary object that no longer exists. – David Schwartz Nov 18 '15 at 20:03
  • @DavidSchwartz - I'd say they're different in pretty important ways. For example just having an invalid iterator sitting around is not itself going to cause UB. Accessing it will unless you correct the problem by like reseating it, but just having it won't. Returning a reference to temporary or to automatic data instantly causes UB and makes the program ill-formed. – Edward Strange Nov 18 '15 at 20:22
  • Agree with @CrazyEddie. And this is important because compilers are allowed to do crazy stuff with ill-formed programms in regards to optimizations. – SergeyA Nov 18 '15 at 20:28
  • @CrazyEddie I don't think that's correct. And if it was, it would be very difficult to write correct programs. Do you have a reference for the claim that the mere existence of a reference to an object that is no longer valid is UB? Normally, we just make sure we don't access objects that no longer exist. Assuring that no references to them exist would be quite burdensome. I'd settle for evidence that returning a reference to a temporary is UB. I couldn't find any. – David Schwartz Nov 18 '15 at 20:31
  • @SergeyA If this distinction is important, why is it that extensive google searching hasn't found anyone clarifying it anywhere? I couldn't find a single page anywhere discussing whether returning a reference to a temporary without accessing it was UB or not. (Do you even know for sure? I don't.) – David Schwartz Nov 18 '15 at 20:40
  • I have asked [a question](http://stackoverflow.com/questions/33790065/undefined-behavior-and-temporaries) to resolve this. :) – David Schwartz Nov 18 '15 at 20:50
  • Shouldn't have thrown myself into language lawer stuff. I am not the one. – SergeyA Nov 18 '15 at 20:52
  • If it's destroyed after return from begin. how come the entire matrix is printed successfully except for the first 2 elements? If it's destroyed after a return from begin, i would expect it to print only the first element correctly. @DavidSchwartz – One_Curious_User Nov 19 '15 at 07:26
  • @COOKIE If we move to level bellow: **1)** `Destroyed` mean that memory whcih occupied by object is marked as free, it is not mean, that something disappear. **2)** In release mode of compilation iterator to vector become just pointer on popular `c++` compilers. And as result you have to pointers to memory that can be used at any time by somebody else, but it is not prevent you to print content of this memory. And you may even print all right values. – fghj Nov 19 '15 at 08:27
  • anyway, I still do not understand how to solve this issue. – One_Curious_User Nov 19 '15 at 09:16
  • @COOKIE The simple way to make result of `matrixToVector` data member of class – fghj Nov 19 '15 at 09:21
  • @COOKIE You have no good reason to expect it to behave in any particular way. Undefined behavior is called "undefined" for a reason, and it almost never does what you expect. – David Schwartz Nov 19 '15 at 17:28