Joh*_*554 2 c++ arrays vector argv
我正在尝试修改程序,以便当参数传递到 argv 时可以修改它们,然后创建一个新数组并用于执行。目前,我正在创建一个 const char* 向量,以便在构建数组之前保存值。
当我构建向量时,我更改的任何值都会作为随机数据而不是我正在构建的字符串(我构建了一个字符串,然后使用 c_str() 将其传递给向量)。下面是代码:
int main(int argc, char const *argv[])
{
std::vector<const char*> args;
for(uint i = 0; i < (uint)argc; i++)
{
if(((string)argv[i] == "-t" || (string)argv[i] == "--test") && (uint) argc - 1 > i)
{
string testPath = test::testPath().lexically_normal().string();
if (boost::filesystem::exists(argv[i+1]) && !strstr(argv[i+1], testPath.c_str()))
{
if (boost::filesystem::is_regular_file(argv[i+1]))
{
boost::filesystem::path p(argv[i+1]);
boost::filesystem::path newPath = test::testPath().lexically_normal();
newPath /= "/ImportedTests";
if (!boost::filesystem::exists(newPath.lexically_normal()))
{
if(boost::filesystem::create_directory(newPath.lexically_normal()))
cout << "An error occurred creating the import directory for specified tests at " << newPath << endl;
}
newPath /= p.filename();
cout << "newPath = " << newPath << endl;
if(boost::filesystem::extension(newPath) == ".nuk" || boost::filesystem::extension(newPath) == ".div")
{
if (rename(argv[i+1], newPath.c_str()) != 0)
cout << "Error importing tests." << endl;
}
args.push_back(argv[i]);
args.push_back(newPath.c_str());
cout << "newPath.c_str() = " << newPath.c_str() << endl; // Prints readable output.
i++;
}
else
{
boost::filesystem::path p(argv[i+1]);
boost::filesystem::path newPath = test::testPath().lexically_normal();
newPath /= "/ImportedTests";
if (!boost::filesystem::exists(newPath.lexically_normal()))
{
if(boost::filesystem::create_directory(newPath.lexically_normal()))
cout << "An error occurred creating the import directory for specified tests at " << newPath << endl;
}
for (const auto & entry : fs::directory_iterator(argv[i+1]))
{
if (boost::filesystem::extension(entry.path()) == ".sol" || boost::filesystem::extension(entry.path()) == ".yul" )
{
if (rename(entry.path().c_str(), newPath.c_str()) != 0)
cout << "Error importing tests." << endl;
}
}
args.push_back(argv[i]);
args.push_back(newPath.string().c_str());
cout << "newPath.c_str() = " << newPath.c_str() << endl;
i++;
}
}
}
else
{
args.push_back(argv[i]);
}
}
for(uint i = 0; i < args.size(); i++){
cout << "element " << i << " = " << args[i] << endl; // when new path is printed here it is not readable. It's just random characters.
}
}
Run Code Online (Sandbox Code Playgroud)
我没有编写此应用程序,因此我无法更改 argv 传递到应用程序的方式而不引起问题。我只想构建相同类型的数组并根据需要修改值。
输出如下:
newPath.c_str() = /home/dev/Development/test/ImportedTests
element 0 = test/tools/isoltest
element 1 = --vm
element 2 = ../../evmone-0.8.0-linux-x86_64/lib/libevmone.so
element 3 = -t
element 4 = Dy8^
Run Code Online (Sandbox Code Playgroud)
如果我可以将此字符串正确地转换为 const char* 我想我可以使用 args.data() 从 args 向量中获取一个数组,然后将其传递给应用程序的其余部分。
如果这完全是愚蠢的,我提前道歉。
args.push_back(newPath.c_str());
Run Code Online (Sandbox Code Playgroud)
返回的指针c_str()
归其返回对象所有。在这里,这个对象是newPath
。当该对象被销毁(或者该对象被修改)时,返回的值const char *
不再有效。
该newPath
对象在其语句结束时if()
、其范围结束时被销毁。newPath
是在if()
语句内声明的,因此它会在语句末尾被销毁。这就是 C++ 中所有对象的工作方式。
然后,显示的代码稍后会尝试取出const char *
,args
当它拥有newPath
,此时它的所有权只是一个遥远的记忆。
这就是未定义行为和观察到的垃圾的原因。
您必须完全重新设计并从根本上重构所显示代码的逻辑,以便const char *
只要此字符指针存在,拥有所有这些的对象就不会被破坏。
一个更简单的解决方案是完全摆脱字符指针。制作args
一个std::vector<std::string>
, 并将args.push_back(newPath)
其放入其中。每当需要使用底层const char *
s 时,获取它们并仅根据需要使用它们,并且无需对底层向量进行任何更改。