C++ how to work with pointers to vector pointers

I have this design:

vector<string*>* tmp = new vector<string*>;

how do i put elements into it? I can not understand how I put in this vector a few strings. I tried it

std::string srt = "abc";
tmp->push_back(srt);

but the compiler curses and the syntax is incorrect, I don't know how to do

just dont get too pointer-ish (assuming this is a relatively simple program)

vector<string> tmp;
std::string srt = "abc";
tmp.push_back(srt);

certainly a vector of pointers to string is a a disaster waiting to happen . And probably you dont need a pointer to a vector either

C Programming Tutorial for Beginners, Learn C the Hard Way: Practical Exercises on the Computational Subjects You Keep Avoiding (Like C) "C" comes from the same letter as "G". The Semites named it gimel.The sign is possibly adapted from an Egyptian hieroglyph for a staff sling, which may have been the meaning of the name gimel.Another possibility is that it depicted a camel, the Semitic name for which was gamal.Barry B. Powell, a specialist in the history of writing, states "It is hard to imagine how gimel = "camel" can be

The syntax would be tmp->push_back(&srt);

But it would be better to use vector<string> because the vector will take care of the pointers for you.

Prefer:

std::vector<std::string> tmp;
std::string srt{"abc"};
tmp.push_back(srt);

"C" Programming Language: Brian Kernighan, This course will give you a full introduction into all of the core concepts in the C programming Duration: 3:46:13 Posted: Aug 15, 2018 Ç or ç is a Latin script letter, used in the Albanian, Azerbaijani, Manx, Tatar, Turkish, Turkmen, Kurdish, Zazaki, and Romance alphabets. Romance languages that use this letter include Catalan, French, Friulian, Ligurian, Occitan, and Portuguese as a variant of the letter C. It is also occasionally used in Crimean Tatar and in Tajik to represent the /d͡ʒ/ sound. It is often retained in the spelling of loanwords from any of these languages in English, Basque, Dutch, Spanish and other

To answer your question:

How to work with pointers to vector pointers?

Let's look at a basic example...

#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;
}

-Expected Output-

Hello World

However, this will compile but fails at runtime and causes an access violation error within Visual Studio. This fails because once the strings pointers go out of scope they are destroyed and the memory that the vector or vector* is trying to reference is now invalid. You might be able to get past this by using dynamic memory, but even then it just makes the code more complicated and harder to manage and can lead to even more unseen errors.

If we fix the above to the following snippet, the code will then work:

#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;
}

This will work with dynamic memory and will provide the following output:

Hello World

However, to avoid all of these errors and complexity of the code simply just don't use any pointers, especially when working with std::string.



The first solution will work but can lead to problems if any of the pointers become invalid before they are used and is tricky to avoid the runtime errors.

There is no need to use pointers in this situation. You are not storing derived classes of a base class where you need inheritance nor polymorphism.

Due to the behavior of std::vector and std::string simply doing this:

#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;
}

Will produce the same expected results without any dynamic memory allocation and memory cleanup, without any errors, and without any code complications since std::vector and std::string manages their own memory.

-Output-

Hello World

This version of the code is much easier to read, cleaner to work with and debug, easier for others to use and will do exactly what you would expect it to do. This solution is very simple, fast and efficient without all of the hassle.

Why C is so Influential - Computerphile, "C" is one of the most widely used programming languages of all time. Prof Brian Kernighan Duration: 8:26 Posted: Aug 18, 2015 Stock analysis for Citigroup Inc (C:New York) including stock price, stock chart, company news, key statistics, fundamentals and company profile.

Using a vector your way can, but shouldn't, be done absent a compelling reason and I'm unable to think of one.

vector<string*>* tmp = new vector<string*>;

This is how you have to do it:

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;
}

Alternately, one could use the indirection operator -> instead of *. They do the same thing but both look ugly in different places.

    tmp->push_back(&srt);
    cout << *tmp->operator[](0) << endl;

Let's examine what is happening with *(*tmp)[0]. (*tmp) is the vector pointed to by tmp. (*tmp)[0] is the contents of the first element in the vector which is a pointer to a string. *(*tmp)[0] is that string pointed to by the first element in the vector.

Aside from the somewhat obscure syntax, beware of strings pointed to by elements in the vector going out of scope which will create dangling pointers.

This is the canonical way to use containers to store strings.

int main()
{
    vector<string> tmp;
    string srt = "abc";
    tmp.push_back(srt);
    cout << tmp[0] << endl;
}

How easy is it to learn C?, Why is C such an influential language? We asked ardent C fan Professor Brailsford. Brian Duration: 10:50 Posted: Aug 25, 2017 C-- (pronounced cee minus minus) is a C -like programming language. Its creators, functional programming researchers Simon Peyton Jones and Norman Ramsey, designed it to be generated mainly by compilers for very high-level languages rather than written by human programmers.

How is C programming language still used today?, - and extremely flexible. So flexible, in fact, that as you use the language, you probably go through many different programming styles as you work out how to use the language to produce good, maintainable, reliable code. This is a list of operators in the C and C++ programming languages.All the operators listed exist in C++; the fourth column "Included in C", states whether an operator is also present in C. Note that C does not support operator overloading.. When not overloaded, for the operators &&, ||, and , (the comma operator), there is a sequence point after the evaluation of the first operand.

Which programs are written in C language?, is best choice when you start programming as it is most basic. C++ is a middle-level programming language developed by Bjarne Stroustrup starting in 1979 at Bell Labs.C++ runs on a variety of platforms, such as Windows, Mac OS, and the various versions of UNIX. This C++ tutorial adopts a simple and practical approach to describe the concepts of C++ for beginners to advanded software engineers.. Why to Learn C++. C++ is a MUST for students and working

Learn C, . Some of the examples are operating systems, more specifically OS kernels, device drivers and interfaces, etc. C# (pronounced see sharp, like the musical note C♯, but written with the number sign) is a general-purpose, multi-paradigm programming language encompassing strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines. It was developed around 2000 by Microsoft as part of its .NET initiative and

Comments
  • Just use vector<string> directly
  • @Justin I do not understand how
  • You can push back pointers to strings. tmp->push_back(&str); But if you don't understand pointers, dynamic allocation and mechanisms behind it and the need to use shared pointeres here, nothing will save you.
  • You do not need both pointers there. std::vector<std::string> will do nicely to you, as it did to millions and millions happy customers before you.
  • @user9431986 I do not understand how -- What seems strange to me is why you would think std::vector<std::string*>* would be easier to use than simply have std::vector<std::string>.
  • tmp->push_back(&srt) will compile, but it will throw a runtime error: Access Violation Error at least within Visual Studio.
  • @FrancisCugler It works without error for me on Visual Studio. How did you read the value? You can use *((*tmp)[0]).
  • @ Wally ah okay, I had forgotten about the double indirection on the actual pointer to vector...
  • pvWords is initialized to nullptr. You can't access it. The second code block doesn't compile. Leave off the = nullptr
  • @doug I had thought so, but for some reason or another if I don't initialize it, I'm getting compiler errors...
  • You have two programs. The first one doesn't compile if you leave off = nullptr but you left off semi-colons at the end of the "Hello" and "World" strings. And the second one doesn't compile as is, but if you remove = nullptr from the second one it will compile and run correctly. The reason the first one compiles (aside from the semi's) but doesn't run is that it needs to be initialized with new vewctor<string>();, not a nullptr. If you do that it will also compile and run.
  • @doug, The missing semi-colons is a typo. Thank you for pointing that out.
  • I assumed it was just a typo. It's a good idea to copy code back from stackoverflow and compile it to check for typos. I've found some on posts I've made and it helps others trying to duplicate problems. Especially for those new to C++. The language can be intimidating at times.