error: "cannot create std::vector larger than max_size()"

HI

I have overloaded the >> operator as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
     std::istream& operator>> (std::istream& in, const Mything& thing) {

       // get data from the istream object into a stringstream
       std::stringstream buffer;
       buffer << in.rdbuf();

       std::cout << "\nSIZE:"<< buffer.str().size() << std::endl;

       //construct a vector<char> from the str of the stringstream object
       std::vector<char> doc_str (buffer.str().begin(), buffer.str().end());

       //load a c_string into an xml parser
       rapidxml::xml_document<> mydoc;
       mydoc.parse<0>(&doc_str[0]); // this needs a non-const c-string so pass a reference to the first element of a vector<char>

       return in;
     }


This produces the following when testing the input operator on myThing:

1
2
3
4
SIZE:5091
terminate called after throwing an instance of 'std::length_error'
  what():  cannot create std::vector larger than max_size()
Aborted (core dumped)


Given the small size of buffer.str(), I cannot understand why a length_error is being thrown when constructing the vector<char> from buffer.str().

By the way, if anyone knows of an easier way way get a non-const c string into the xml parse function, please let me know. buffer.str().c_str() does not work as it returns a const c string.

Thanks
std::vector<char> doc_str (buffer.str().begin(), buffer.str().end());
begin() and end() are iterators to two different, temporary objects [the results of your str() calls].

You should use iterators to the same (and therefore, non-temporary) string object for both parameters.

In fact, there's almost no point to using a vector<char> here. Just use a std::string and pass in my_str.data(). Edit: Nevermind, as rozick mentioned .data() is still const. You can use &my_str[0], though, similar to what you've already done.
Last edited on
ah, a stupid error - i thought it returned a reference

thanks very much

btw: my_str.data() returns a const c string, the parser needs a non-const string
Last edited on
Ah you're right, and I see the documentation for rapidxml that
Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used.
so the non-constness is indeed on-purpose.

The creation of the vector could still be avoided if you do std::string doc_str = buffer.str(); and then pass &doc_str[0] as you already have it.
Last edited on
For C++17, .data() returns non-const.
That's what it was! I made the mistake of only checking cplusplus.com...
I made the mistake of only checking cplusplus.com...


That's way out of date as it only covers up-to C++14. We're now on C++20!
I have overloaded the >> operator as follows:

What are you trying to achieve?

Let’s say the suggested code works – if I’ve understood correctly, it should look more or less like:
1
2
3
4
5
6
7
8
9
10
11
std::istream& operator>> (std::istream& in, const Mything& thing) {

    // get data from the istream object into a stringstream
    std::stringstream buffer { in };

    //load a c_string into an xml parser
    rapidxml::xml_document<> mydoc;
    mydoc.parse<0>( buffer.str().data() );

    return in;
}


What should it do?
Your overloaded operator>> will anyway read from a std::stream. If you want to input data from an xml file, wouldn’t you need something like:
 
void operator>> (rapidxml::xml_document<>& in, const Mything& thing)

or similar?
I'm not quite sure what you mean.

The idea is that the client code will look something like this:

1
2
3
4
5
6
7

ifstream xmlfile ("something.xml");

Mything thing;

xmlfile >> thing;


That input operator would then call the overloaded operator>> set out above. This will then copy the content from the ifstream object into a string which will be parsed by the xml parser. The parsed result will be used to load the private member variables of the Mything object.

Is this a poor approach? I think your approach assumes that the client has access to the xml parser?

Thanks
In the original post, nothing is actually done with the Mything object inside the operator>> function, so that may have been part of the confusion. That fact that you have the object marked as const is even more confusing, because it appears you are intentionally passing the object but not doing anything with it.

Operator overloading can be abused. Given "stream_object >> other_object;", a C++ programmer would normally assume that other_object is being modified in some way.

What you're doing will work. Yes, Enoziat's approach does require the user to make the xml_document object and pass it. Your approach assumes that the in-stream for operator>> is formatted as an XML document. I would make a comment for the operator>> saying that it expects 'in' to be xml document text, and/or change the variable name of 'in' to be 'xml_text' or something like that.
Last edited on
Topic archived. No new replies allowed.