Я пытаюсь отладить проблему, связанную с областью массива символов, содержащейся в 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?
Последняя строка выходных данных показывает, что глобальный указатель на C-строку в порядке, даже если включающий std :: string находится вне области видимости. Итак, когда возвращаемое значение выходит из области видимости и массив строк удаляется? Любая помощь от сообщества приветствуется. Благодарю.
Значение указателя не изменится, но память, на которую он указывает, может больше не быть частью строки.
objtype
неверно в строке сразу после установки в set_objtype()
потому что результат get_objtype () нигде не сохраняется, поэтому компилятор может убить его тут же.
Это может работать, но оно обращается к недопустимой памяти, поэтому это недопустимый код, и если вы полагаетесь на такие вещи, вы в конечном итоге столкнетесь с большими проблемами.
Вы должны посмотреть на разборку, используя objdump, чтобы проверить, является ли его RVO.
Но из экспериментов, которые я провел (сделал глобальный результат и скопировал его), похоже, что c_str подсчитывается по ссылке.