从std::vector<>转换为双指针?

4

出于好奇,我想知道是否可以将std::vector<>转换为双指针。

以这种方式将std::vector作为指针传递我从未遇到过问题:

std::vector<char> myCharVector;
myCharVector.push_back('a');
myCharVector.push_back('b');
myCharVector.push_back('c');
char *myCharPointer = &myCharVector[0];

我很好奇是否有可能以类似的方式分配指针的地址:

char *myPointer = "abc";
char **myDoublePointer = &myPointer; 

我已经尝试过:

char **myDoublePointer = (char**)&myCharVector;

但它不起作用。有没有实现这个目标的方法?

这是出于好奇心以外的任何目的吗? - user541686
你在这行代码中遇到了什么错误:char **myDoublePointer = (char**)&myCharVector; - weidi
@weidi 没有错误。 - kbirk
@Pondwater 那么,正如你所说的,什么没有起作用? - weidi
3个回答

8

您已经知道&myCharVector[0]是一个指向char的指针。所以如果您将其存储在变量中:

char *cstr = &myCharVector[0];

然后,您可以获取该变量的地址:
char **ptrToCstr = &cstr;

但是仅仅像这样进行两次取消引用是不够的:
char **ptrToCstr = &(&myCharVector[0])

这是无效的,因为值(&myCharVector[0])尚未存储在内存中。


它肯定在内存中,但它是一个rvalue,因此为了安全起见,禁止获取其地址。 - GManNickG
不一定,它可能在寄存器中。 - japreiss
很好。为了澄清我的评论,让编译器分配临时堆栈空间以允许其地址被获取并不难。例如,给定 char*& to_lvalue(char*&& x) { return x; },你可以写成 char** ptrToCstr = &to_lvalue(&myCharVector[0]),但是该指针在语句之后将无法使用,这就是我所说的安全预防措施。 - GManNickG

4
在C++11中,您可以这样做:
char *myCharPointer = myCharVector.data();

但是你不能获取data()返回值的地址,因为它并没有返回底层存储的引用,只有指针值。

如果目的是为了能够更改指针所指向的内容,则可能真正需要一个指向向量的指针,而不是指向字符的指针。但是,STL不会让你直接在向量内更改底层指针,除非通过常规的向量API(如resizeswap)。


3
你绝对不能这样做。 std::vectorchar ** 是完全不同的对象类型,你不能仅仅将一个转换为另一个。

你之所以能够执行 char *myCharPointer = &myCharVector[0] 是因为 myCharVector[0] 给出了一个 char,因此 &myCharVector[0] 给出了该 char 的地址,你可以将其分配给 char *

唯一可能将完整的 std::vector 转换为 char *(而不是 char **)的方法是循环遍历你的 std::vector 并手动从数据构建一个 char *

例如像这样:

char *ptr = malloc(myCharVector.size()+1);
for (unsigned int i=0; i < myCharVector.size(); i++) {
  ptr[i] = myCharVector[i];
}
ptr[myCharVector.size()] = 0;

然后,ptr 将是一个由 char 组成的 C 字符串。

@BenVoigt,您是什么意思?转换为char *的部分是什么意思? - houbysoft
需要复制向量以获得连续块(以便指针下标工作)的部分是错误的。vector内容保证存储连续,因此&v[i] == i + &v[0] - Ben Voigt
@BenVoigt:是的,但只要向量不被修改就可以正常工作,对吗? - houbysoft
你必须小心任何使迭代器无效的操作。并非所有修改都会导致迭代器无效(替换或删除元素不会有问题,除非您提前保留了空间)。插入操作会导致迭代器无效,除非您提前保留了空间。 - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接