gpt4 book ai didi

c++ - 从 vector 到 char** 的转换只携带第一个元素

转载 作者:太空宇宙 更新时间:2023-11-04 15:17:53 25 4
gpt4 key购买 nike

我已经针对我的问题对下面的代码进行了大量评论。基本上问题是我试图伪造 argv通过 std::vector<std::string>但是我从 Visual Studio 得到了我不期望的行为。您能否详细说明我在这里缺少什么?

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.

最佳答案

tl;dr 您调用 glutInit是错的。见下文。


尽管许多其他贡献者声称,您的个人 C 字符串非常好地以 NULL 终止,因为在 C++11(您正在使用的)中它保证为 str.operator[](str.size())评估为空字符:

[C++11: 21.4.5]:

const_reference operator[](size_type pos) const;
reference operator[](size_type pos);

1 Requires: pos <= size().
2 Returns: *(begin() + pos) if pos < size(), otherwise a reference to an object of type T with value charT(); the referenced value shall not be modified.

(严格来说,这并不是说 *(&str.operator()(str.size()-1)+1)charT() ,而是 NULL 必须 存储在实际数据缓冲区中,以便实现遵守字符串的恒定时间访问保证。)

因此根本没有必要求助于存储 str.c_str() 的结果,尽管这是一种有效的替代方法。

而且,因为 vector 默认初始化它们的成员,你的 argv本身也是空终止的。

因此你的vector没有问题;当我抽象出 OpenGL 时,我无法重现您的问题:

#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

( live demo )

然而,glutInit需要一个指向数据缓冲区大小的指针,而不是大小本身。所以,当你经过 argv.size() ,那是错误的。

试试这个:

int argv_size = argv.size();
glutInit(&argv_size, argv.data());

关于c++ - 从 vector<string> 到 char** 的转换只携带第一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27551900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com