2

我正在尝试将 a 转换为std::vector<std::string>以 NULL 结尾的 C 样式字符串数组 ( char *)。new是否可以不使用/进行复制malloc

基本上,我想在没有 new/malloc 的情况下将 vec 转换回与 arr 完全相同的东西。

#include <string>
#include <vector>
#include <stdio.h>
using namespace std;

void print(const char **strs)
{
   const char **ptr = strs;
   while(*ptr) {
      printf("%s ", *ptr);
      ++ptr;
   }
}

void print(std::vector<std::string> &strs) {
   for(auto iter = strs.begin(); iter != strs.end(); ++iter) {
      printf("%s ", iter->c_str());
   }
}

void main()
{
   const char *arr[] = { "a", "b", "c", "d", "e", "f", NULL };

   vector<string> vec;

   const char **str = arr;
   while(*str) {
      vec.push_back(*str);
      ++str;
   }
   vec.push_back((char *) NULL); //Doesn't work

   //print(vec);
   print((const char **) &vec[0]);
}
4

4 回答 4

5

仅通过设置指向该向量开头的指针是不可能的,因为vector<string>它不是您期望的连续字符。

                   addr1   addr2    addr3
                    ^        ^        ^
                    |        |        |
                +--------+--------+--------+----
                |   |    |   |    |   |    |
                |  std:: |  std:: |  std:: |
       +---->   | string | string | string | ...
       |        |        |        |        |
       |        +--------+--------+--------+----
       |
       |
       |
 vector<string> 

addr1addr2并且addr3是内存中的随机地址。

因此,解决方案是遍历项目,读取字符串和字符并将它们放入您的 continue 数组中。

于 2013-04-19T15:31:30.237 回答
2

您需要自己构建指针数组,如果在编译时不知道大小,则需要动态分配。(在这个例子中,你可以从sizeof arr; 但我假设arr当你需要重建它时它不可用)。

可以使用指向由向量管理的字符串的指针,因此您不需要为它们分配任何内存。

所以你可以得到你需要的数组:

std::vector<char const *> vec2;
vec2.reserve(vec.size()+1); // optional, but might improve efficiency
for (auto const & str : vec) {
    vec2.push_back(str.c_str());
}
vec2.push_back(nullptr);

print(vec.data());
于 2013-04-19T15:48:36.703 回答
0

是否可以不使用 new/malloc 进行复制?

如果您的 C++ 编译器支持可变长度数组作为扩展,那么它就是。否则,您将不得不使用动态内存分配。

std::vector<std::string> vec;
// initialize `vec', etc.

const char *c_strings[vec.size()];
size_t idx = 0;
for (std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); it++) {
    c_strings[idx++] = it->c_str();
}
于 2013-04-19T15:30:51.010 回答
0

好的,所以您不能在 a 中存储“NULL” std::vector<std::string>,我认为这是您的目标。

重点std::vector是它跟踪中的条目数std::vector::size()

但是,如果您确实需要一些可以传递给 print 之类的函数的东西,那么您可以执行以下操作:

vector<const char *> v;

for(auto iter = vec.begin(); iter != vec.end(); ++iter) {
   v.push_back(iter->c_str());
}
v.push_back(NULL);

print(&v[0]);
于 2013-04-19T15:35:05.417 回答