I am trying to concatenate two strings in C 11 and I am often getting an unexpected behavior.
First, I have a function that converts any type to string :
template <class T>
static inline const char * toStr(T arg) {
stringstream ss;
ss << arg;
return (ss.str()).c_str();
}
Then, I use this function like this :
string measure_name;
for (unsigned long j = 0; j < 1280; j ) {
measure_name = string("ADC_") toStr(j);
cout << measure_name << endl;
}
Everything goes well untill I reach a 4 digit number (> 999) :
my variable measure_name
often equals to "ADC_ADC_"... and it happens randomly. I did some research and found nothing about this strange behavior.
For your information, this issue is fixed if toStr
returns a string
and not a const char *
.
Also, if I try to print the returned value, I never see it equal to "ADC_ADC_", so I believe the real issue comes from the concatenating instruction :
string measure_name;
for (unsigned long j = 0; j < 1280; j ) {
const char* tmp = toStr(j);
if (!strcmp(toStr(j), "ADC_ADC_"))
cout << "bug" << endl; //never happens
measure_name = string("ADC_") tmp; //problem comes from here
cout << measure_name << endl;
}
I just wanted to understand what I am doing wrong there... I know I am using very old C but it should work anyway.
Thank's for your help.
CodePudding user response:
Here
return (ss.str()).c_str();
You are returning a pointer to the buffer of a temporary std::string
(returned from str()
). The pointer returned from the function is useless for the caller, because the std::string
it points to is already gone.
A pointer is just a pointer. If you want a string, return a std::string
. If you want to return a const char*
then you need to store the string somewhere and manage its lifetime.
std::string
does mangage the lifetime of a character array, so just do:
template <class T>
static inline std::string toStr(T arg) {
stringstream ss;
ss << arg;
return ss.str();
}
If someone needs a c-array of char
they can still call c_str
(and use it as long as the std::string
is still alive).
Instead of your toStr
consider to use std::to_string
.