Can <sstream> really be so big?

29 Jun 2012

I have a question here about memory usage. I have a bunch of working code on my mbed (main.cpp is around 1000 lines, plus around 10 libraries, some standard and some I've written).

The startup reads a configuration file and initialises a bunch of objects using various pins (6 Pwms, a few DigitalIns and DigitalOuts).

Now I want to start using the HTTP client, which means I need to create a HTTPMap with a load of pair<std::string,std::string>. Most of the things I need to post will be ints and floats, so I included <sstream> and have:

#include <sstream>

void someCallback() {

  stringstream ss1;

  ...

  ss1 << someChars;
  parameters.insert(pair<std::string,std::string>("id",ss1.str()));
  ss1.str("");
  ss1 << ctTime;
  parameters.insert(pair<std::string,std::string>("time",ss1.str()));
  ss1.str("");

  ...

  HTTPClient http;
  http.post(...);
}

int main () {
  while(1) {
    etc....
  }
}

Once I make these changes, my code stopped about 20% into the initialisation routine. I've run into this before when I was storing a bunch of vector<MyObject> type things, and it went away once I changed it to vector<MyObject*>

So I started commenting things out, and I narrowed it down to the following:

#include <sstream>

void someCallback() {

  stringstream ss1;

  // never use ss1
}
int main() {
  etc...
}

My code now stops 20% through the initialisation, merely by including sstream and creating a variable inside a function, which is never referenced again. I can't really believe that merely including sstream uses more memory than the rest of my program (which is creating at various times 10 - 20 vectors of ints, strings, and more complex objects). So can anyone shed some light on what is going on, and if I'm wrong and sstream really does require more memory than the mbed has on board, could someone suggest a more efficient way of converting my ints to std:string for use with HTTPClient library?

Many thanks, Paul.

29 Jun 2012

Note that I am really unfamiliar with this stuff.

But a quick test shows the same here, just including what you wrote in an empty program kicks RAM usage to 37%, which seems kinda excessive. You can use iostream instead, still uses 25% RAM, but might do it. Then just use sprintf to convert int to char array, and char array to string next (strcpy apparently can be used for that).

29 Jun 2012

In my opinion, streams is probably the most bloated and useless part of the standard C++ library. They certainly should not be used when you have limited RAM.

Quote:

could someone suggest a more efficient way of converting my ints to std:string

Just use sprintf or itoa with a fixed-size char buffer. Using sstream just for this is definitely an overkill.

04 Jul 2012

Thanks for the replies. I did end up using sprintf and it worked.

A follow up question...is there a resource anywhere for embedded programming which discusses which libraries should be avoided?

Also, when I look at the build details for the build which had streams in it, it gave RAM usage at 49%. Are there certain constructs which the build details can't figure out memory usage, or is it just not that accurate?

04 Jul 2012

The build diagram only shows the RAM used at startup, by the variables that need to be placed into writable memory. All stack and heap usage during runtime comes on top of that.