-1

I'm trying to return a string from a function that does some processing.

I've tried returning it as an rvalue reference and also as an lvalue reference. didn't work :(.

processing function:

std::string processingFunction()
{
    std::string str = "";
    //processing...
    strftime(&str[0], MAX_LENGTH, DATE_FORMAT, tm_STRUCT_ADRRESS);
    return str;
}

use of the function:

std::string temp = processingFunction();
if(temp.empty())
{
    //stuff
}

When debugging (in VS 2019), I can see the value of temp in the Watch, but temp.empty() always returns 1. Even if I can see that the value is present.

here is a screenshot for tl;dr: m_bucket_function is the processing function

3 Answers3

2

You define a std::string object and set it to "" (the empty string).

You then use strftime() to copy, as a C-style string, a representation of some time to memory starting at &str[0].

The expression &str[0] (where str is a std::string) does give you access to the initial byte of the data managed by the str::string object -- but it doesn't allocate memory to hold the new value, and it doesn't update the std::string object's internal data (including the length of the string it represents). Your call to strftime() is likely to clobber unallocated memory (undefined behavior).

You need to use strftime() to copy data into a char array, and then copy that data into your str. std::string's assignment operator will then take care of updating the metadata and allocating memory as needed.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
1

There's no problem with returning a std::string by value, as you're doing.

temp.empty() always returns 1

just means the string is empty.

Now that you've posted more code and as @SkyZip comments, the problem lies in:

strftime(&str[0], ...

this gets strftime to overwrite memory by passing it the address of your string.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • but it's not empty, I can see its content. – Eyal Kamitchi Oct 20 '19 at 21:37
  • Try printing `temp` and `temp.empty()` after the function returns. Either it'll be empty or not. – Paul Evans Oct 20 '19 at 21:42
  • It's not empty because strftime writes in it! It WILL modify the string's 'value' but not its size information nor anything else. Hence your empty string. – skyzip Oct 20 '19 at 21:46
  • You are welcome, but see the other's answer's. They explained the problem very well. I posted a solution which might work in your case, but maybe you should look for a more 'c++' style solution instead. – skyzip Oct 20 '19 at 21:56
0

If you really have to use strftime you can do it like so:

std::string processingFunction()
{
    char buff[MAX_LENGTH];
    strftime(buff, MAX_LENGTH, DATE_FORMAT, tm_STRUCT_ADRRESS);
    //processing...
    return std::string(buff);
}



And as @Keith said, you are working with objects here. Not just plain old C data types.

Edit:
Just for reference, here is a similar question: Current date and time as string

skyzip
  • 237
  • 2
  • 11
  • `return std::string(buff);` could simply be `return buff;` since the return value will be converted to `std::string` anyway. – PaulMcKenzie Oct 21 '19 at 02:38
  • Yes, it could be. But to my understanding, that would be an implicit way to call the constructor, and most of the time, I'd rather use the explicit way. With conversions, too. – skyzip Oct 21 '19 at 07:45
  • I hate to be picky (disclaimer: I **love** to be picky), but C++'s meaning for the word "object" is not related to object-oriented programming. For example, given `int foo = 42;`, `foo` is an object. – Keith Thompson Oct 21 '19 at 18:47
  • Sorry, my English vocabulary still needs to improve in this regard. What choice of words do you suggest to make my point more clear? – skyzip Oct 21 '19 at 23:09