Archived

This forum has been archived. Please start a new discussion on GitHub.

problem with string sequences

There seems to be a problem in implementing out parameter for string sequences:
void
IceInternal::BasicStream::read(vector<string>& v)
{
Int sz;
readSize(sz);
while(sz--)
{
string s;
read(s);
v.push_back(s);
}
}

Vector is not cleared, therefore it just keeps growing, causing memory problems in client code like :

Test::AStruct input,output;
for (int i=0; i<num_elems; ++i) {
input.iseq.push_back(i);
input.sseq.push_back("abcd");
}


for (int i=0;i<num_calls;++i) {
twoway->foo(input,output);
}

Time after = Time::now();

If we change BasicStream::read as :

void
IceInternal::BasicStream::read(vector<string>& v)
{
Int sz;
readSize(sz);
v.clear();
v.reserve(sz);
while(sz--)
{
string s;
read(s);
v.push_back(s);
}
}

problem goes away.

Comments

  • mes
    mes California
    Welcome!

    Thanks for the bug report, this will be corrected in the next release.

    Take care,
    - Mark
  • Hello,

    I had been working a bit on improving performance when passing lots of string sequences and I came up with another version which might be of some interest:
    void
    IceInternal::BasicStream::read(vector<string>& v)
    {
        Int sz;
        readSize(sz);
    
        std::vector<std::string> result(sz);
        std::vector<std::string>::iterator it = result.begin();
        std::vector<std::string>::iterator const end = result.end();
        
        for(; it != end; ++it)
        {
    	read(*it);
        }
        v.swap(result);
    }
    

    This gave me a significant performance improvement (on my platform RH9 + gcc3.2.2) and has the advantage of leaving the vector in a consistent state if an exception is thrown.

    Cheers,
    Bertrand.
  • marc
    marc Florida
    Interesting idea, thanks for the suggestion! We will try this.
  • The swap trick is mentioned in Effective STL by Scott Meyers to reduce the size of the vector.