How to append to std::string in linked list fashion?

Posted on 2004-08-12
Last Modified: 2013-12-14
I think this is an extremely difficult question. Urgency can be measured in months.

I work in a large company that uses std::string as its string choice. The application we code is a database application, and it often does hundreds of thousands of appends to a single string for a single report (The format we output is XML). The data in a report can be anywhere from 1k, to about 1gig. My group has developed a wrapper around this template class, but when we pass a std::string to library, we can not pass our own class, so this problem needs to somehow be handled in the std::string class itself. Maybe via the allocator object.

The problem is, these appends slow us down because of all the allocation and string copying that must be done each append. If we could somehow have std::string store all the appends in a linked-list, and then combine it once, when we need it, this would be an ideal solution. Any speed-ups that can be provided could be helpful though.

We need this in the std::string itself because this is the only object we can pass to other libraries that need to read or write to the string. While we could make sure the string was concatenated before passing it outside of our code, this is very dangerous and tedious since it's easy to forget.

Allocating more space than needed would help, but wouldn't be an ideal solution since it would hamper performance. The large range in amount of data that can be returned makes it difficult to guess how much would be good since a single append is generally anywhere from 2 bytes to 400 bytes.

I wasn't able to understand how the allocator class could be overridden since we need to combine all the data when it is needed.
Question by:Crius
LVL 86

Accepted Solution

jkr earned 250 total points
ID: 11789816
>>While we could make sure the string was concatenated before passing it outside of our code,
>>this is very dangerous and tedious since it's easy to forget

Bu, that IMHO is the way to go. You could take out the tediousness and danger about forgetting about that by automating the task if you offer a conversion operator that is applies when these functions are called.

>>I wasn't able to understand how the allocator class could be overridden

See e.g the sample here, maybe that helps: ("A Custom Block Allocator for Speeding Up VC++ STL")
LVL 30

Assisted Solution

Axter earned 50 total points
ID: 11792835
If you're compiling in VC++ 5.0/6.0, or 7.x, the std::string class that comes with these compilers are very inefficient.
Consider replacing the std::string class with another library, or using CString instead.

CString is far more efficient that the std::string that comes with VC++.
LVL 30

Expert Comment

ID: 11792878
>>The problem is, these appends slow us down because of all the allocation and string
>>copying that must be done each append.

IMHO, you should cosider addressing this differently all together.

I recommend you try using std::list<std::string> instead.

Exactly how are you appending the data?

Do you have example code?

It might be that you just need to tweek the append code.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Assisted Solution

anthony_w earned 200 total points
ID: 11793121
SGI provide a rope class which supports addition without reallocating. I believe this is still part of STLPort (, which is based on the original SGI implementation of the STL.

If you use your own custom class for handling the string building, then you can give it a conversion to std::string (either explicit, with a named function, or implicit with a conversion operator), which you can then call when you pass it to the external interface.

Author Comment

ID: 11794534
Thank you for these feedbacks. First I would like to address some of the problems encountered with some of these solutions:

Using std::string is a company-wide mandate, and can not be changed. We were using a far more efficient string class before, but we had to change our class to derive from std::string. This can not be changed. It is not up to our smallish group. In fact, this change to std::string is what is prompting this question, otherwise, there would not be any problems.

A conversion operator was considered, but most of our calls to external code pass by reference, and I couldn't figure out how to do a concatenation during a call if we pass by reference.

An example of our append code is as follows:
(where string1, string2, and string3 are std::string)
string1 += string2;
string1 = string2+string3;

If we can use conversion operators to guarantee we can concantenate our string when it gets passed outside our code (by pointer, by reference, and by copy) then this would be a perfect solution!!!

We *must* derive our class from std::string however, and this brought up the problem - while we are sure our functions are the only ones used in our code, we could be assured this would not be the case when we passed our string outside of our code. Doing a dir of our *.cpp files only, we have 33 megs of code. Our string class is used everywhere, so changing the way we call external functions (we are very chatty) would not be feasible. We really need an automatic way of doing it without changing the interface/calling.

A block allocator would help, but as stated in my original problem, we don't want to use much more memory than needed, and we use a ton of strings, and their sizes differ greatly. A linked list is a great way to go, and std::list is basically this. If only we could use this instead of std::string.

There are many great solutions out there, but we must use std::string. It's a flexible class it seems, although I really don't understand how it works. I am hoping there's a way to have std::string behave more like a linked list in implementation.

Author Comment

ID: 11847750

If you could supply me with the conversion operators that would automatically be called when we are calling a function with the std::string as an argument, I would be very happy to award you an A.

We need to handle the following 3 possibilities:
1) Passed by value
2) Passed by reference
3) Passed by pointer

Passed by value can be done via a custom copy constructor.
How do I do the other two?

Author Comment

ID: 11847852
Oops, also for anthony_w - it looks like this is the way to go...

Since we are required to derive our class from std::string... Well, will a str::string conversion operator still work? Will it be called, or will the compiler just say, "Hey, you're already a std::string, so I won't call the conversion operator?".

Author Comment

ID: 11856646
After some tinkering and testing I was able to prove that the compiler will not call a user-defined conversion operator if the object is already what you want.

IE: Creating a class that inherits from std::string will cause any std::string conversion operators in the class to never be called.

I admit this question was far too specific with too many restrictions placed on it:
1) I have to inherit from std::string.
2) I need to pass my string class to outside functions.
3) I want it to have fast appending, like a linked-list can provide.

As such, I doubt there is a solution. I will split the points according to how much effort I felt were put in. It's unfortunate most of my questions get the answer of "It can't be done" in the end, but I admit, I would have been shocked if someone had come up with a way to do this.

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

680 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question