0

I am trying to debug a problem related to the scope of the character array contained within a std::string. I have posted the relevant code sample below,

#include <iostream>
#include <string>

const char* objtype;

namespace A
{

std::string get_objtype()
{
  std::string result;
  std::string envstr( ::getenv("CONFIG_STR") );
  std::size_t pos1 = 0, pos2 = 0, pos3 = 0;
  pos1 = envstr.find_first_of("objtype");
  if (pos1 != std::string::npos)
    pos2 = envstr.find_first_of("=", pos1+7);
  if (pos2 != std::string::npos)
  {
    pos3 = envstr.find_first_of(";", pos2+1);
    if (pos3 != std::string::npos)
      result = envstr.substr(pos2+1, pos3 - pos2 - 1);
  }
  const char* result_cstr = result.c_str();
  std::cerr << "get_objtype()" << reinterpret_cast<long>((void*)result_cstr) << std::endl;
  return result;
}

void set_objtype()
{
  objtype = get_objtype().c_str();
  std::cerr << "Objtype " << objtype << std::endl;
  std::cerr << "main()" << reinterpret_cast<long>((void*)objtype) << std::endl;
}

}

int main()
{
  using namespace A;
  std::cerr << "main()" << reinterpret_cast<long>((void*)objtype) << std::endl;
  set_objtype();

  if (::strcmp(objtype, "AAAA") == 0)
    std::cerr << "Do work for objtype == AAAA " << std::endl;
  else
    std::cerr << "Do work for objtype != AAAA" << std::endl;
}

This was compiled and executed on MacOS 12.3 with g++ 4.2.1. The output from running this is as follows,

$ g++ -g -DNDEBUG -o A.exe A.cpp
$ CONFIG_STR="objtype=AAAA;objid=21" ./A.exe
main()0
get_objtype()140210713147944
Objtype AAAA
main()140210713147944
Do work for objtype == AAAA
$

My questions are these: The pointer value printed from main() and get_objtype() are the same. Is this due to RVO? The last line of output shows that the global pointer to C-string is ok even when the enclosing std::string is out of scope. So, when does the returned value go out of scope and the string array deleted? Any help from the community is appreciated. Thanks.

6
  • The returned string in get_objtype() is destroyed right after the statement. i.e. after hitting the semicolon. It's just that the address that objtype is pointing is not overwritten with any other data. Hence you are still seeing the value "AAAA". Commented Apr 30, 2013 at 4:31
  • BTW, what are you trying to acheive with this example ? Unless you are doing something different, make the code simpler and easy. Commented Apr 30, 2013 at 4:33
  • I am trying to understand an existing piece of code. Commented Apr 30, 2013 at 4:35
  • Compiled and executed on Mac OS 12.3? When did that come out? Commented Apr 30, 2013 at 5:41
  • @Michael. Are you not getting this output? Commented Apr 30, 2013 at 11:04

2 Answers 2

1

The pointer value won't change, but the memory it points to may no longer be part of a string.

objtype is invalid on the line right after you set it in set_objtype() because the result of get_objtype() isn't saved anywhere, so the compiler is free to kill it there and then.

It may work, but it's accessing invalid memory, so it is invalid code and if you rely on things like this, you will eventually run into big problems.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. So will the compiler create a temp string before calling c_str() on that?
There is an anonymous string "existing" until the semicolon on the line objtype = get_objtype().c_str(); The get method returns an actual string (on the stack).
0

You should look at the disassembly using objdump to check if its RVO.

But, from experiments I did (making result global and making copies of it), it looks like c_str is reference counted.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.