c++for-looppointersvectoriostream

How to collect doubles from user input and print them using a "pointer" to a "vector"?


It is a code that gets some doubles from the user input, and then prints them.
Input looks like this 1 2 3 4.5 x, where x is an arbitrary non-double to break the first for loop.
However, it segfaults!

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<double> *b;
    for (double i; cin >> i;)
    {
        b->push_back(i);
    }

    for (double j:(*b))
    {
        cout << j << endl;
    }
    return 0;
}

Solution

  • It segfaults because the b pointer doesn't point to anything. Dereferencing an uninitialized pointer leads to undefined behavior, which may include a segmentation fault.

    You could dynamically allocate the vector so that the pointer actually points to valid memory. Remember to explicitly delete it.

    #include <iostream>
    #include <vector>
    
    int main() {
        auto b = new std::vector<double>();
    
        for (double i; std::cin >> i;) {
            b->push_back(i);
        }
    
        for (double j : *b) {
            std::cout << j << "\n";
        }
    
        delete b;
        return 0;
    }
    

    Or use a smart pointer.

    #include <iostream>
    #include <vector>
    #include <memory>
    
    int main() {
        auto b = std::make_unique<std::vector<double>>();
    
        for (double i; std::cin >> i;) {
            b->push_back(i);
        }
    
        for (double j : *b) {
            std::cout << j << "\n";
        }
    
        return 0;
    }
    

    But your best bet is to drop the pointer entirely and just use a vector.

    #include <iostream>
    #include <vector>
    
    int main() {
        std::vector<double> b;
    
        for (double i; std::cin >> i;) {
            b.push_back(i);
        }
    
        for (double j : b) {
            std::cout << j << "\n";
        }
    
        return 0;
    }
    

    If you're concerned with stack memory usage, don't be. Barring providing your own customer allocator that changes the behavior of std::vector, this container dynamically allocates its storage already.