C ++如何使用指向向量指针的指针
Posted
技术标签:
【中文标题】C ++如何使用指向向量指针的指针【英文标题】:C++ how to work with pointers to vector pointers 【发布时间】:2019-01-09 18:49:59 【问题描述】:我有这个设计:
vector<string*>* tmp = new vector<string*>;
如何将元素放入其中? 我不明白我是如何在这个向量中放入一些字符串的。 我试过了
std::string srt = "abc";
tmp->push_back(srt);
但是编译器会诅咒,语法不正确,不知道怎么办
【问题讨论】:
直接用vector<string>
就行了
@Justin 我不明白如何
您可以将指针推回字符串。 tmp->push_back(&str);
但是如果你不了解指针、动态分配及其背后的机制以及这里需要使用共享指针,那么没有什么能拯救你。
那里不需要两个指针。 std::vector<std::string>
会对你有好处,就像它对你之前的数百万满意的客户一样。
@user9431986 我不明白如何 -- 让我感到奇怪的是为什么你会认为std::vector<std::string*>*
比简单地使用std::vector<std::string>
更容易使用。
【参考方案1】:
只是不要太指针式(假设这是一个相对简单的程序)
vector<string> tmp;
std::string srt = "abc";
tmp.push_back(srt);
当然,指向字符串的指针向量是一场等待发生的灾难。而且可能你也不需要指向向量的指针
【讨论】:
【参考方案2】:语法是tmp->push_back(&srt);
但最好使用vector<string>
,因为向量会为您处理指针。
喜欢:
std::vector<std::string> tmp;
std::string srt"abc";
tmp.push_back(srt);
【讨论】:
tmp->push_back(&srt)
会编译,但会抛出运行时错误:至少在 Visual Studio 中出现访问冲突错误。
@FrancisCugler 它在 Visual Studio 上对我来说没有错误。您是如何读取该值的?你可以使用*((*tmp)[0])
。
@Wally 啊好吧,我忘记了指向vector
的实际指针上的double indirection
...【参考方案3】:
回答你的问题:
如何使用指向向量指针的指针?
让我们看一个基本的例子......
#include <iostream>
#include <string>
#include <vector>
int main()
// has to be initialized since it is a pointer.
// However, this will compile but will fail at runtime.
std::vector<std::string*>* pvWords = nullptr;
std::string word1 = "Hello";
std::string word2 = "World";
// Here you need the `operator->()` from the vector
// and since it will store pointers to strings,
// you can just pass in the address of...
pvWords->push_back( &word1 );
pvWords->push_back( &word2 );
for ( auto& s : *pvWords ) // here we need to dereference pvWords
std::cout << *s << ' '; // and here we need to dereference s
std::cout << '\n';
return 0;
-预期输出-
Hello World
但是,这将编译但在运行时会失败,并导致 Visual Studio 中出现访问冲突错误。这会失败,因为一旦strings
指针超出范围,它们就会被销毁,并且vector
或vector*
试图引用的内存现在无效。您也许可以通过使用动态内存来解决这个问题,但即便如此,它只会使代码更复杂、更难管理,并可能导致更多看不见的错误。
如果我们将上述修复为以下 sn-p,则代码将起作用:
#include <iostream>
#include <string>
#include <vector>
int main()
std::vector<std::string*>* pvWords = new std::vector<std::string*>;
std::string word1 = "Hello";
std::string word2 = "World";
pvWords->push_back( &word1 );
pvWords->push_back( &word2 );
for ( auto& s : (*pvWords) )
std::cout << (*s) << ' ';
std::cout << '\n';
delete pvWords; // don't forget to cleanup dynamic memory.
return 0;
这将与动态内存一起使用,并将提供以下输出:
Hello World
但是,为了避免所有这些错误和代码的复杂性,只需不要使用任何指针,尤其是在使用 std::string
时。
第一个解决方案可以工作,但如果任何指针在使用前变为无效,并且很难避免运行时错误,则可能会导致问题。
在这种情况下不需要使用指针。您没有在需要继承或多态性的地方存储基类的派生类。
由于std::vector
和std::string
的行为,只需这样做:
#include <iostream>
#include <string>
#include <vector>
int main()
std::vector<std::string> vWords;
vWords.push_back( "Hello" );
vWords.push_back( "World" );
for ( auto& s : vWords )
std::cout << s << ' ';
std::cout << '\n';
return 0;
由于std::vector
和std::string
管理它们自己的内存,因此将产生相同的预期结果,无需任何动态内存分配和内存清理、没有任何错误和任何代码复杂性。
-输出-
Hello World
此版本的代码更易于阅读、更易于使用和调试,更易于其他人使用,并且完全符合您的预期。此解决方案非常简单、快速且高效,没有任何麻烦。
【讨论】:
pvWords 被初始化为 nullptr。你无法访问它。第二个代码块无法编译。离开= nullptr
@doug 我是这么认为的,但是由于某种原因,如果我不初始化它,我会遇到编译器错误...
您有两个程序。如果您省略了= nullptr
,但您在“Hello”和“World”字符串的末尾省略了分号,则第一个不会编译。第二个不会按原样编译,但是如果您从第二个中删除= nullptr
,它将正确编译和运行。第一个编译(除了半编译)但没有运行的原因是它需要用new vewctor<string>();
初始化,而不是nullptr。如果你这样做,它也会编译并运行。
@doug,缺少的分号是错字。感谢您指出这一点。
我认为这只是一个错字。从 *** 复制代码并编译它以检查拼写错误是个好主意。我在我发布的帖子中找到了一些内容,它可以帮助其他尝试复制问题的人。特别是对于那些刚接触 C++ 的人。这种语言有时会令人生畏。【参考方案4】:
在没有令人信服的理由的情况下,可以但不应该以你的方式使用矢量,我想不出一个。
vector<string*>* tmp = new vector<string*>;
你必须这样做:
using std::vector; using std::string; using std::cout;
int main()
vector<string*>* tmp = new vector<string*>;
string srt = "abc";
(*tmp).push_back(&srt);
cout << *(*tmp)[0] << endl;
delete tmp;
或者,可以使用间接运算符->
而不是*
。他们做同样的事情,但在不同的地方看起来都很丑。
tmp->push_back(&srt);
cout << *tmp->operator[](0) << endl;
让我们看看*(*tmp)[0]
发生了什么。 (*tmp)
是tmp
指向的向量。 (*tmp)[0]
是向量中第一个元素的内容,它是指向字符串的指针。 *(*tmp)[0]
是向量中第一个元素所指向的字符串。
除了有点晦涩难懂的语法之外,请注意向量中的元素指向的字符串超出范围会产生悬空指针。
这是使用容器存储字符串的规范方式。
int main()
vector<string> tmp;
string srt = "abc";
tmp.push_back(srt);
cout << tmp[0] << endl;
【讨论】:
以上是关于C ++如何使用指向向量指针的指针的主要内容,如果未能解决你的问题,请参考以下文章