编辑:在实施James Hopkin的建议后,我仍然收到“无效名称'null'”的警告,这比那些奇怪的字符要好得多。然后,我回去再次读取库文档,结果发现,对于该特定函数,它的参数应该还有一个非NULL字符串元素而不是aNames的大小。附加字符串还有其他用途。添加一个字符串后,代码运行正常。这都是我的错,我很抱歉。
原帖:
嗨,
这是我的第一篇文章,所以请你好。我在这个论坛搜索并用Google搜索,但我仍然找不到答案。这个问题困扰了我一天多,所以请给我一些帮助。谢谢。
我需要将一个字符串向量传递给库函数foo(char const * const * const)。我不能传递& Vec [0],因为它是一个指向字符串的指针。因此,我有一个数组并将c_str()传递给该数组。以下是我的代码(aNames是字符串的向量):
const char* aR[aNames.size()];
std::transform(aNames.begin(), aNames.end(), aR,
boost::bind(&std::string::c_str, _1));
foo(aR);
但是,它似乎会导致一些未定义的行为:
如果我运行上面的代码,那么函数foo会在aR中抛出一些关于非法字符('èI'blablabla)的警告。
如果我在函数foo之前打印aR:
std::copy(aR, aR+rowNames.size(),
std::ostream_iterator<const char*>(std::cout, "\n"));
foo(aR);
然后,一切都很好。 我的问题是:
转换是否会导致未定义的行为?如果是这样,为什么?
将字符串向量传递给foo(char const * const * const)的正确方法是什么?
答案 0 :(得分:5)
由于foo
只接受一个指针,我的猜测是它需要一个以NULL结尾的数组。为aR
分配一个额外的元素并为其分配NULL。
我的建议是:
std::vector<const char*> c_strings;
c_strings.reserve(aNames.size() + 1);
std::transform(
aNames.begin(), aNames.end(),
std::back_inserter(c_strings),
boost::bind(&std::string::c_str, _1)
);
c_strings.push_back(0);
foo(&c_strings[0]);
答案 1 :(得分:1)
嗯,这对我来说似乎是对的。 c_str创建一个以null结尾的char数组,该数组在下一个非const字符串操作之前是常量。将c_str指针存储在const char *数组中。
我不是助推专家所以问题可能存在,但我的猜测是你的向量中的字符串是一个与函数foo中预期的编码不兼容的编码。
从编码的角度检查您的代码。
MY2C
答案 2 :(得分:1)
试试这个:
std::vector<char*> arr(aNames.size()+1);
for(size_t i = 0; i < aNames.size(); ++i)
arr[i] = aNames[i].c_str();
arr[arr.size()-1] = NULL; // just in case
foo(&arr[0]);