0

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

これは、MacOS 12.3 と g++ 4.2.1 でコンパイルおよび実行されました。これを実行した場合の出力は次のとおりです。

$ 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-string へのグローバル ポインターが問題ないことを示しています。では、戻り値が範囲外になり、文字列配列が削除されるのはいつですか? コミュニティからの助けに感謝します。ありがとう。

4

2 に答える 2

1

ポインター値は変更されませんが、ポインターが指すメモリーは文字列の一部ではなくなる可能性があります。

objtypeset_objtype()get_objtype() の結果はどこにも保存されないため、設定した直後の行では無効です。したがって、コンパイラはその場で自由に強制終了できます。

動作するかもしれませんが、無効なメモリにアクセスしているため、無効なコードであり、このようなものに依存すると、最終的に大きな問題が発生します。

于 2013-04-30T04:30:10.763 に答える