samedi 1 octobre 2016

Using unique_ptr with vector

I'm trying to convert written code used by shared_ptr to unique_ptr because in the code of its usage seems shared_ptr unnecessary and it will be an exercise with smart pointers. As far as I can detect with debugger the problem is on v.at(i)->push_back(t);. So, as soon as a value entered, the program crashes.

Working code with shared_ptr:

#include <iostream>
#include <iomanip>
#include <memory> // For smart pointers
#include <vector> // For vector container
#include <locale> // For toupper()
using std::vector;
using std::shared_ptr;
int main()
{
    vector <shared_ptr<vector<double>>>records; // Temperature records by days
    size_t day{ 1 }; // Day number
    char answer{}; // Response to prompt
    double t{}; // A temperature
    while (true) // Collect temperatures by day
    { // Vector to store current day's temperatures created on the heap
        auto pDay = std::make_shared<vector<double>>();
        records.push_back(pDay); // Save pointer in records vector
        std::cout << "Enter the temperatures for day " << day++
            << " separated by spaces. Enter 1000 to end:\n";
        while (true)
        { // Get temperatures for current day
            std::cin >> t;
            if (t == 1000.0) break;
            pDay->push_back(t);
        }
        std::cout << "Enter another day's temperatures (Y or N)? ";
        std::cin >> answer;
        if (toupper(answer) == 'N') break;
    }
    double total{};
    size_t count{};
    day = 1;
    std::cout << std::fixed << std::setprecision(2) << std::endl;
    for (auto record : records)
    {
        std::cout << "\nTemperatures for day " << day++ << ":\n";
        for (auto temp : *record)
        {
            total += temp;
            std::cout << std::setw(6) << temp;
            if (++count % 5 == 0) std::cout << std::endl;
        }
        std::cout << "\nAverage temperature: " << total / count << std::endl;
        total = 0.0;
        count = 0;
    }
}

Output:

23 34 29 36 1000
Enter another day's temperatures (Y or N)? y
Enter the temperatures for day 2 separated by spaces. Enter 1000 to end:
34 35 45 43 44 40 37 35 1000
Enter another day's temperatures (Y or N)? y
Enter the temperatures for day 3 separated by spaces. Enter 1000 to end:
44 56 57 45 44 32 28 1000
Enter another day's temperatures (Y or N)? n

Temperatures for day 1:
23.00 34.00 29.00 36.00
Average temperature: 30.50

Temperatures for day 2:
34.00 35.00 45.00 43.00 44.00
40.00 37.00 35.00
Average temperature: 39.13

Temperatures for day 3:
44.00 56.00 57.00 45.00 44.00
32.00 28.00
Average temperature: 43.71

The converted code with unique_ptr:

#include <iostream>
#include <vector>
#include <memory>
#include <iomanip>

using std::vector;


int main()
{ // Function scope starts here

    // a vector(outside) holding unique_ptrs to a vector(inside) which type is double
    vector<std::unique_ptr<vector<double>>> v;
    size_t day{ 1 };
    char answer{};
    double t{};


    while (true)
    {
        size_t i{};
        auto pDay = std::unique_ptr<vector<double>>();
        v.push_back(std::move(pDay));

        std::cout << "Enter the temperatures for day " << day++
            << " separated by spaces. Enter 1000 to end:\n";

        while (true)
        {
            std::cin >> t;
            if (t >= 1000.0) break;
            v.at(i)->push_back(t);
            ++i;
        }

        //std::cout << v.at(0)->at(0) << std::endl;
        std::cout << "Enter another day's temperatures (Y or N)? ";
        std::cin >> answer;
        if (toupper(answer) == 'N') break;
    }

    double total{};
    size_t count{};
    day = 1;
    std::cout << std::fixed << std::setprecision(2) << std::endl;

    for (auto const& record : v)
    {
        std::cout << "\nTemperatures for day " << day++ << ":\n";
        for (auto temp : *record)
        {
            total += temp;
            std::cout << std::setw(6) << temp;
            if (++count % 5 == 0) std::cout << std::endl;
        }
        std::cout << "\nAverage temperature: " << total / count << std::endl;
        total = 0.0;
        count = 0;
    }

} // Function scope ends here

enter image description here

Aucun commentaire:

Enregistrer un commentaire