Ошибка выполнения при использовании push_back () для умного указателя на вектор - PullRequest
1 голос
/ 18 апреля 2019

Я пытаюсь заполнить вектор, разыменовывая смарт-указатель. Во время выполнения программа вылетает после одной итерации первого цикла for, используемого для ввода переменной input.

using namespace std;

class Measurement
{
protected:
    int sample_size;
    string label;
    shared_ptr <vector<double>> data;
public:
    // parameterised constructor
    Measurement(string pLabel, int pSample_size)
    {
        label = pLabel;
        sample_size = pSample_size;
        cout << "Please input your dataset one entry at a time:" << endl;
        for (int i = 0; i < sample_size; i++)
        {
            double input;
            cin >> input;
            data->push_back(input); // NOT WORKING???
        }
    }
};

int main()
{
    Measurement A("xData", 5);
    return 0;
}

При использовании отладчика VS выдается исключение (Исключение: нарушение прав чтения. std :: _ Vector_alloc>> :: _ Myend (...) вернул 0xC.) в векторный файл, в частности строки 1793 - 1795:

bool _Has_unused_capacity() const _NOEXCEPT
    {   // micro-optimization for capacity() != size()
    return (this->_Myend() != this->_Mylast());

В чем причина этой ошибки?

Ответы [ 3 ]

2 голосов
/ 18 апреля 2019

Значение по умолчанию shared_ptr не указывает на что-либо действительное.From https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr:

Создает shared_ptr без управляемого объекта, т. Е. Пусто shared_ptr.

Вам необходимо инициализировать его так, чтобы он указывал на действительный объект, который онуправляет, прежде чем вы можете использовать базовый указатель.Например, измените конструктор на:

Measurement(string pLabel, int pSample_size) : data(new std::vector<double>()) 
{
   ...
}

или

Measurement(string pLabel, int pSample_size) : data(std::make_shared<std::vector<double>>()) 
{
   ...
}
1 голос
/ 18 апреля 2019

Вам необходимо выделить память для data перед ее использованием:

Measurement(string pLabel, int pSample_size) {
   ...
   data = std::make_shared<vector<double>>();
   ...
}
0 голосов
/ 18 апреля 2019

Вы никогда не инициализировали ptr. Ниже демонстрируется использование инициализаторов по умолчанию для переменных-членов и списков инициализаторов элементов .

Вы можете легко добавить инициализацию ptr в список инициализации, но, поскольку он не зависит от аргументов конструктора. Лучше объявить его конструкцию следующим образом, чтобы избежать ошибки копирования / вставки при создании дополнительных конструкторов.

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

using namespace std;                                                             

class Measurement {                                                              
  protected:                                                                     
    int                        sample_size_;                                     
    string                     label_;                                           
    shared_ptr<vector<double>> data_{make_shared<vector<double>>()};             

  public:                                                                        
    // parameterised constructor                                                 
    Measurement( string pLabel, int pSample_size )                               
      : sample_size_( pSample_size )                                             
      , label_( pLabel )                                                         
    {                                                                            
        cout << "Please input your dataset one entry at a time:" << endl;        
        for ( int i = 0; i < sample_size_; i++ ) {                               
            double input;                                                        
            cin >> input;                                                        
            data_->push_back( input ); // NOT WORKING???                         
        }                                                                        
    }                                                                            

    friend ostream& operator<<( ostream& os, Measurement const& op1 )            
    {                                                                            
        for ( auto& v : *op1.data_ )                                             
            os << v << " ";                                                      
        return os;                                                               
    }                                                                            
};                                                                               

int main()                                                                       
{                                                                                
    Measurement A( "xData", 5 );                                                 
    cout << A << endl;                                                           
    return 0;                                                                    
}  

Выход:

g++     example.cpp   -o example
Please input your dataset one entry at a time:
1
2
3
4
5
1 2 3 4 5 
...