By far the easiest way to handle this is to create a new stringstream object every time you want it to be empty. In most cases (including yours) this is easily handled by simply letting the existing object go out of scope, and having a new one that's created when you re-enter the correct scope.
Personally, I'd do the job by moving all the code to convert from int to std::string into a function that has a local stringstream object, so a "clean" stringstream is created every time you call the function, and destroyed when you leave it.
std::string to_string(long int in) {
std::stringstream buffer; // New/empty every time this function is called
buffer << in;
return buffer.str();
} // here buffer goes out of scope and is destroyed.
int main()
{
long int max = 0;
for(int i=10;i<100; i++){
for(int j = i; j < 100; j++) {
long int product = static_cast<long>(i)*j;
std::string str = to_string(product);
// presumably:
// if (product > max) max = product;
std::cout << str;
// you never seem to use this:
//int size = str.length();
}
}
cout<<max;
return 0;
}
A couple of notes: if your compiler is reasonably recent, it may already have an std::to_string in its standard library, so you can just use that instead of writing your own.
Also note the cast to long before multiplying i and j. Given the values you're using right now, this isn't strictly necessary, but neither is the use of long for product. Assuming you might ever use values where product could be larger than will fit in an int, the cast becomes necessary. Without it, you're doing multiplication on two ints, which naturally produces an int result. Then you're taking that result (which has already overflowed if it's too large to fit in an int) and converting it to long. By converting one of the operands to long before the multiplication, you force the multiplication to be carried out on longs as well, preventing the overflow (at least assuming long is large enough to hold the result).