繁体   English   中英

从返回的std :: string的本地副本获取C字符串

[英]Getting C-string from local copy of returned std::string

我正在尝试调试与std :: string中包含的字符数组范围有关的问题。 我已经在下面发布了相关的代码示例,

#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;
}

它是使用g ++ 4.2.1在MacOS 12.3上编译和执行的。 运行此命令的输出如下,

$ 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
$

我的问题是:从main()和get_objtype()打印的指针值是相同的。 这是由于RVO吗? 输出的最后一行显示,即使封闭的std :: string超出范围,指向C字符串的全局指针也是可以的。 那么,何时返回的值超出范围并删除字符串数组? 感谢社区的任何帮助。 谢谢。

指针值不会改变,但是它指向的内存可能不再是字符串的一部分。

set_objtype()设置它之后, set_objtype()objtype无效,因为set_objtype()的结果未保存在任何地方,因此编译器可以自由地在那里杀死它。

它可能会起作用,但是它正在访问无效的内存,因此它是无效的代码,如果您依靠这样的事情,最终将遇到很大的问题。

您应该使用objdump查看反汇编,以检查其RVO。

但是,从我做过的实验(使结果全局化并对其进行复制)来看,c_str看起来像是引用计数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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