Вы используете метод c_str
временного строкового объекта ("--graph=" + conf.root())
, который возвращает указатель на внутренний буфер этого строкового объекта, который больше не действителен после строки.
Вы можете использовать это вместо этого:
std::string graph_option = "--graph=" + conf.root();
argv[idx++] = graph_option.c_str();
Эта строка не будет удалена до execvp
, потому что переменная не будет go за пределами области видимости раньше.
Причина, по которой она иногда работала с недопустимым объектом в том, что возвращаемый указатель по-прежнему будет указывать на то место, где раньше находился буфер. Когда вы вызывали c_str
, объект был все еще действителен, и даже если бы это было не так, вы все равно получили бы что-то от метода, обычно нет проверки против использования объектов после их уничтожения.
Если это буфер не перезаписывается между вызовом деструктора и использованием значения, старое значение будет прочитано, и, похоже, все работает. В зависимости от строковой реализации и размера строки буфер может находиться в куче или внутри самого строкового объекта (в стеке). В любом случае память можно было использовать повторно или нет. Вы используете отладчик, чтобы проверить, что на самом деле происходит в вашей системе, но любое изменение даже в несвязанных частях вашей программы, в стандартной библиотеке или компиляторе может изменить результат.
Ключевой концепцией C ++ является термин «неопределенное поведение». Это означает, что нет абсолютно никаких ограничений на то, что происходит в вашей программе при нарушении определенных условий. Это позволяет разработчикам языка (в основном компиляторам и стандартной библиотеке) производить оптимизацию, предполагая, что неопределенное поведение никогда не произойдет.