Nezo
Nezo

Reputation: 597

How to avoid taking address of a temporary variable?

The way my code is currently set up, I feel that I have to choose between a segmentation fault and making a pointer to a temporary object. The code is below:

#include <memory>
#include <cstddef>
#include <iostream>

template <typename T> class Node;

template <typename T> class List {
    public:
        typedef std::size_t size_type;
        typedef T value_type;
        typedef T& reference;
        typedef const T& const_reference;

        class iterator {
            public:
                iterator() {
                    isNull = true;
                }
                iterator(const T val) {
                    isNull = false;
                    data = val;
                    prev = this;
                    next = &iterator();  #PROBLEMATIC LINE
                }
                iterator operator++() {
                    if(this->next->isNull)
                        return iterator();
                    iterator old_it = *this;
                    this->prev = &old_it;
                    this->next = this->next->next;
                    this->data = this->next->data;
                    return *this;
                }
                T& operator*() {
                    return data;
                }
                iterator* next;
                iterator* prev;
                T data;
                bool isNull;
        };

        List() {
            _begin = iterator();
            _end = _begin;
        }

        List(size_type n, T val) {
            _begin = iterator(val);
            _end = *(_begin.next);
            _end.prev = &_begin;
        }

        void push_back(T val) {
            iterator temp = iterator();
            _end.data = val;
            _end.next = &temp;
            temp.prev = &_end;
            _end = temp;
        }

        iterator begin() {return _begin;}
        iterator end() {return _end;}
    private:
        iterator _begin;
        iterator _end;
};

int main() {
    List<int> derp= List<int>(3,3);
    List<int>::iterator i = derp.begin();
    std::cout << *i;
    derp.push_back(4);
    std::cout << i.data;
    ++i;
    std::cout << *i;
}

The above takes the address of a temporary variable. When I change the problematic line from

next = &iterator();

to

*next = iterator();

The code gets a segmentation fault, but I don't know why. Any help would be appreciated. As well as any egregious flaws in the code that you might happen to notice.

Upvotes: 0

Views: 566

Answers (2)

david.pfx
david.pfx

Reputation: 10868

The first error is because you have to find a place to store the created object, before you can store a pointer to it. A temporary object will disappear -- you have to put it somewhere.

The second error is because have to initialise a pointer before you can dereference it. It has to point to something.

But there is a conceptual problem. An iterator is an object that is the logical equivalent of a pointer. A pointer-to-iterator would be equivalent to pointer-to-pointer. So your next and prev members should either be pointer-to-node or iterator, not pointer-to-iterator.

If you can make your code work the way you want with either of these, the other problems will go away. I don't really get the point of the whole thing, so I can't tell you how to do that.

Upvotes: 1

wuqiang
wuqiang

Reputation: 644

*next = iterator() leads to segmentation fault because you use a uninitialized pointer. next = &iterator() is also very bad.See this:Temporary Objects

just assign next to NULL;

Upvotes: 0

Related Questions