Reputation: 51
This is a simple class and simple test function:
#include <queue>
#include <string>
namespace {
using namespace std;
}
class NameStream {
queue<string> stream;
public:
string operator * () { return stream.front(); }
NameStream &operator ++(int) { stream.pop(); return *this; }
NameStream &operator ++() { stream.pop(); return *this; }
NameStream &operator <<(string name) { stream.push(name); }
operator bool() { return !stream.empty(); }
};
inline void nameStreamTest() {
NameStream &stream = *new NameStream;
stream << "hi" << "hey" << "hoy";
while (stream) {
printf("%s\n", (*stream++).c_str());
}
}
It falls in
NameStream &operator <<(string name) { stream.push(name); }
inside queue's push procedure, here is the stack beyond my code:
#0 0x000b5079 in std::deque<std::string, std::allocator<std::string> >::push_back at stl_deque.h:1055
#1 0x000b50f2 in std::queue<std::string, std::deque<std::string, std::allocator<std::string> > >::push at stl_queue.h:204
#2 0x000b511c in NameStream::operator<< at NameStream.h:24
#3 0x000b520f in nameStreamTest at NameStream.h:32
My experience fails in this case. What am I doing wrong?
P.S.:
NameStream &stream = *new NameStream;
Is used to clear off location of
stream
object at address (offset?) 0x7d (!) which causes same exception.
Upvotes: 4
Views: 2307
Reputation: 69988
Put a return statement at the end of your function.
NameStream &operator <<(string name) { stream.push(name); return *this; }
Add: Not returning a valid reference/value (when needed) will cause a UB and that will cause hidden crashes or bad behavior which are often hard to debug (as in your case). So never ignore a compiler warning if it generates any.
Upvotes: 6
Reputation: 55564
You've got a number of problems in the code.
Missing return in operator<<
(as pointed out by iammilind and others) which causes the runtime error that you observe. It can be corrected as follows:
NameStream &operator <<(string name) { stream.push(name); return *this; }
Another problems is due to the sequence of calls in the body of your while loop which is:
Therefore in the last iteration you first pop()
in operator++(int)
and then try to call front()
in operator*()
on an empty queue which will cause a runtime error.
The easiest way to fix it is to rewrite your while loop as follows.
while (stream) {
printf("%s\n", (*stream).c_str());
++stream;
}
Memory leak. You call allocate a NameStream object using new
, but never call delete
. An easy solution is to allocate your stream object on stack:
NameStream stream;
Upvotes: 0
Reputation: 73443
It is failing as postfix operator ++
is having higher precedence than operator *
, so when for the last iteration of the loop is executed, you first pop
from the queue and then try to do front
by which time queue is empty. To solve this, the simplest way is to break it into two statements like:
while (stream) {
printf("%s\n", (*stream).c_str());
stream++;
}
Upvotes: 2
Reputation: 106106
It falls in
NameStream &operator <<(string name) { stream.push(name); }
You don't return *this
... by chaining the operator<<()
calls, the second and third one have no valid object address to work on.
Upvotes: 0