1

I am trying to fill a vector, by dereferencing a smart-pointer. During runtime the program crashes after one iteration of the first "for" loop used for entering the variable 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;
}

When using the VS debugger it shows that an exception is thrown (Exception thrown: read access violation. std::_Vector_alloc > >::_Myend(...) returned 0xC.) in the vector file, specifically lines 1793 - 1795:

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

What is the cause of this error?

4
  • 2
    Well, what is data pointing to??? Commented Apr 18, 2019 at 18:06
  • 2
    Doesn't look like you ever allocated the object for the smart pointer. Commented Apr 18, 2019 at 18:06
  • 1
    Dereferencing a nullptr (also true for smart pointers) is Undefined Behaviour. Commented Apr 18, 2019 at 18:08
  • @alterigel yeah this is the error, thanks Commented Apr 18, 2019 at 18:17

3 Answers 3

2

A default constructed shared_ptr does not point to anything valid. From https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr:

Constructs a shared_ptr with no managed object, i.e. empty shared_ptr.

You need to initialize it such that it points to valid object that it manages before you can use the underlying pointer. For example, change the constructor to:

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

or

Measurement(string pLabel, int pSample_size) : data(std::make_shared<std::vector<double>>()) 
{
   ...
}
Sign up to request clarification or add additional context in comments.

4 Comments

Using new to initialize the smart pointer results in twice the allocations (~2x slower). Using std::make_shared allocates the space for the object and the tag together.
@CruzJean, please clarify what you mean by twice the allocations. You certainly don't mean twice the allocations for the std::vector, do you?
@RSahu By two allocations he means one for the object and one for the reference counter. I don't see any reason to use new and not make_shared here.
Yeah, this was the silly mistake, thanks. Implemented using make_shared instead of new.
1

You need to allocate memory for data before use it:

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

1 Comment

Thanks for the help!
0

You never initialized the ptr. Below demonstrates the use of default initializers for member variables and member initializer lists.

You could easily add the ptr initialization to the initialization list, but since it doesn't depend on any constructor arguments. It's better to declare it's construction in the manner below to avoid a copy/paste error when creating additional constructors.

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

Output:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.