Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this create a dangling reference?

C26830: Assigning by value when a const-reference would suffice

I'd think that the VS2019 suggestion would create a dangling reference situation, but I tested it out, and it seems to work. What is happening here?


    template<typename MessageType>
    class Queue {
      inline static std::vector<MessageType> messages;
    public:
      static bool isEmpty() {
        return messages.size() == 0;
      }

      template <typename... Args>
      static void emplace(Args&&... args) {
        messages.emplace_back(std::forward<Args>(args)...);
      }

      static MessageType pop() {
        auto const& val = messages.back();
        messages.pop_back();
        return val;
      }
    };

It looks like the last message stays alive long enough to be copied into the return value. Is this good practice?

like image 748
ratiotile Avatar asked May 20 '21 00:05

ratiotile


People also ask

What is a dangling reference?

A link or pointer to an instruction, table element, index item, etc. that no longer contains the same content. If the reference is not a currently valid address, or if it is valid but there is no content in that location, it may cause the computer to crash if the software is not programmed carefully.

How we can avoid the problem of dangling reference?

We can avoid the dangling pointer errors by initialize pointer to NULL , after de-allocating memory, so that pointer will be no longer dangling. Assigning NULL value means pointer is not pointing to any memory location.

How are dangling pointers different from memory leaks?

Generally, daggling pointers arise when the referencing object is deleted or deallocated, without changing the value of the pointers. In opposite to the dangling pointer, a memory leak occurs when you forget to deallocate the allocated memory.


1 Answers

It looks like the last message stays alive long enough to be copied into the return value. Is this good practice?

Unfortunately, no it doesn't, and no it isn't. The return type of std::vector<T>::back is an lvalue reference. Maybe intellisense thinks it is an rvalue reference, in which case its lifetime would be extended because of the rules here.

But it is not the case for this and the usage here is undefined behaviour. This is because the item in the list to which the reference refers has been destroyed. The reason it may still work is because the memory of the item is still there, and so it can be read correctly. This is just luck (or unluckiness, if you want to be able to find these errors). If the item destroyed by pop_back held other memory then you may see a different result, like a SEGFAULT.

like image 138
Fantastic Mr Fox Avatar answered Oct 19 '22 12:10

Fantastic Mr Fox