Proper way to create unique_ptr that holds an allocated array

前端 未结 6 1999
天命终不由人
天命终不由人 2020-12-07 11:31

What is the proper way to create an unique_ptr that holds an array that is allocated on the free store? Visual studio 2013 supports this by default, but when I use gcc versi

相关标签:
6条回答
  • 2020-12-07 11:32

    Seems like a goofup, i will explain what i mean

    class Object {
    private :
        static int count;
    public :
        Object() {
            cout << "Object Initialized " << endl;
            count++;
        }
        ~Object() {
            cout << "Object destroyed " << endl;
        }
        int print()
        {
            cout << "Printing" << endl;
            return count;
        }
    };
    
    int Object::count = 0;
    
    int main(int argc,char** argv)
    {
        // This will create a pointer of Object
        unique_ptr<Object> up2 = make_unique<Object>();  
        up2->print();
        // This will create a pointer to array of Objects, The below two are same. 
        unique_ptr<Object[]> up1 = std::make_unique<Object[]>(30);
        Object obj[30];
        cout << up1.get()[8].print();
        cout << obj[8].print();
    
        // this will create a array of pointers to obj. 
            unique_ptr<Object*[]> up= std::make_unique<Object*[]>(30);
            up.get()[5] = new Object();
            unique_ptr<Object> mk = make_unique<Object>(*up.get()[5]);
            cout << up.get()[5]->print();
    
            unique_ptr<unique_ptr<Object>[]> up3 =  std::make_unique<unique_ptr<Object>[]>(20);
            up3.get()[5] = make_unique<Object>();
    
        return 0;
    }
    

    Objective of the post is that there are hidden small subtle things you need to understand. Creating array of objects is same as object array of unique_ptr. It will make difference only when you pass it in the argument. Creating array of object pointers of unique_ptr is also not very useful. So only below two you need to use in most scenarios.

    unique_ptr<Object> obj;
    //and 
    unique_ptr<unique_ptr<Object>[]>= make_unique<unique_ptr<Object>[]>(20);
    
    0 讨论(0)
  • 2020-12-07 11:35

    Using the T[] specialisation:

    std::unique_ptr<unsigned char[]> testData(new unsigned char[16000]());
    

    Note that, in an ideal world, you would not have to explicitly use new to instantiate a unique_ptr, avoiding a potential exception safety pitfall. To this end, C++14 provides you with the std::make_unique function template. See this excellent GOTW for more details. The syntax is:

    auto testData = std::make_unique<unsigned char[]>(16000);
    
    0 讨论(0)
  • 2020-12-07 11:36

    A most likely better way would be to use std::vector<unsigned char> instead

    #include <vector>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        vector<unsigned char> testData(0x12, 0); // replaces your memset
        // bla    
    }
    

    The advantage is that this is much less error-prone and gives you access to all kinds of features such as easy iteration, insertion, automatic reallocation when capacity has been reached.

    There is one caveat: if you are moving your data around a lot, a std::vector costs a little more because it keeps track of the size and capacity as well, rather than only the beginning of the data.

    Note: your memset doesn't do anything because you call it with a zero count argument.

    0 讨论(0)
  • 2020-12-07 11:40

    Probably something like the following?

    using namespace std;
    
    int size = get_size();
    int const init_value = 123;
    
    unique_ptr<int[]> p = make_unique<int[]>(size)
    fill(p.get(), p.get() + size, init_value);
    
    0 讨论(0)
  • 2020-12-07 11:43

    Use the array version :

    auto testData = std::unique_ptr<unsigned char[]>{ new unsigned char[16000] };
    

    Or with c++14, a better form ( VS2013 already has it ):

    auto testData = std::make_unique<unsigned char[]>( 16000 );
    
    0 讨论(0)
  • 2020-12-07 11:52
    unsigned int size=16000;
    std::unique_ptr<unsigned char[], std::default_delete<unsigned char[]>> pData(new unsigned char[size]);
    
    0 讨论(0)
提交回复
热议问题