C++ 从矢量转换<;字符串>;to char**只携带第一个元素
我已经用我的问题对下面的代码进行了大量的注释。基本上,问题是我试图通过一个C++ 从矢量转换<;字符串>;to char**只携带第一个元素,c++,c++11,C++,C++11,我已经用我的问题对下面的代码进行了大量的注释。基本上,问题是我试图通过一个std::vector来伪造argv,但是我从VisualStudio得到了一个我不期望的行为。请你详细说明我在这里遗漏了什么 std::vector<std::string> argv_storage; for (std::size_t i = 0; i < 10; ++i) { // I copy output of generate_rand_str() because I will nee
std::vector
来伪造argv
,但是我从VisualStudio得到了一个我不期望的行为。请你详细说明我在这里遗漏了什么
std::vector<std::string> argv_storage;
for (std::size_t i = 0; i < 10; ++i)
{
// I copy output of generate_rand_str() because I will need it
// later in the code.
argv_storage.push_back( std::string( generate_rand_str() ) );
}
std::vector<char *> argv( argv_storage.size() + 1 ); // one extra for NULL
for (std::size_t i = 0; i != argv_storage.size(); ++i)
{
argv[i] = &argv_storage[i][0];
}
// Here if I access elements like argv.data()[index]
// they are perfectly fine but when I do:
char** test = argv.data();
// Visual Studio debugger only shows argv.data()[0]
// I want to pass this to glutInit() ...
int argc = argv.size() - 1; // one less for the NULL
glutInit(&argc, argv.data());
// Inspection of arguments passed to glutInit() also shows that ONLY the
// the first element of argv is passed.
std::向量argv_存储;
对于(标准::尺寸i=0;i<10;++i)
{
//我复制generate_rand_str()的输出,因为我需要它
//代码的后面部分。
argv_storage.push_back(std::string(generate_rand_str());
}
std::vector argv(argv_storage.size()+1);//空值另加一个
对于(std::size_t i=0;i!=argv_storage.size();++i)
{
argv[i]=&argv_存储[i][0];
}
//如果我访问argv.data()[index]之类的元素
//它们非常好,但当我这样做时:
字符**测试=argv.data();
//Visual Studio调试器仅显示argv.data()[0]
//我想把这个传递给glutInit()。。。
int argc=argv.size()-1;//空值少一个
glutInit(&argc,argv.data());
//对传递给glutInit()的参数的检查还显示,只有
//传递argv的第一个元素。
tl;dr您对glutInit
的调用是错误的。见下文
尽管许多其他贡献者声称,您的单个C字符串完全以NULL结尾,因为在C++11(您正在使用的)中,
str.operator[](str.size())
可以保证计算为NULL字符:
[C++11:21.4.5]:
const_参考运算符[](size_type pos)const代码>
参考运算符[](大小\类型pos)代码>
1要求:posglutInit
将int*
作为第一个参数,而不是int
你的向量/字符串看起来很凌乱,但很正确 “因此,根本不需要存储str.c_str()的结果(无论如何,只要在str上调用非常量成员,它就会变得不安全)。”在我看来,获取指针&str[0]
不再安全,因为调用非常量成员可能会触发重新分配,然后获取的指针就变得无效。我仍然更喜欢data()
或c_str()
(它们在c++11中做同样的事情)而不是将指针指向字符串的第一个元素,因为这是从字符串对象获取c样式字符串的有文档记录的方法,并且至少可以保证在第一段末尾,你是说空字符吗?@cdhowie:这很公平。@JasonR:是的,我有。。。指针将无效。我不确定指针&str[0]
何时无效是否有严格的保证。(虽然我怀疑一个健全的实现会从data()
和c_str()
返回&str[0]
,但这也不能保证。)最终可能是一样的,所以。。。shrugI实际上传递了一个int*
(上面的代码中没有显示),但是您对glutInit
的评论非常有意义,因为glut修改了argv和argc,因此一切都变得混乱。你有没有一个解决方案是防过剩的?@3p3r:为什么不给我们看看你的实际代码?然后我们可以帮你诊断。而不是为您生成一个新程序。@LightnessRacesinOrbit我更新了它,就是这样。我所有的代码都是这样的,generate_rand_str()实际上是不相关的,因为它来自Lua端,我可以在那里有一个随机字符串生成算法,它与我想要做的没有任何区别。另外,我正在复制它的输出。它返回char*
@3p3r:那么我还是不明白你在问什么。我们已经证明您的代码是正确的。你要求我们告诉你你遗漏了什么,但你没有遗漏任何东西,也没有显示任何相反的证据!
#include <vector>
#include <string>
#include <iostream>
int main()
{
std::vector<std::string> argv_storage;
for (std::size_t i = 0; i < 10; ++i)
{
// I copy output of generate_rand_str() because I will need it
// later in the code.
argv_storage.push_back(std::to_string(i));
}
std::vector<char *> argv( argv_storage.size() + 1 ); // one extra for NULL
for (std::size_t i = 0; i != argv_storage.size(); ++i)
{
argv[i] = &argv_storage[i][0];
}
char** test = argv.data();
while (*test != NULL) {
std::cout << *(test++) << ' ';
}
}
// 0 1 2 3 4 5 6 7 8 9
int argv_size = argv.size();
glutInit(&argv_size, argv.data());