简体   繁体   中英

Unexpected behavior concatenating string

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.

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 usestd::to_string .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM