c++ - কাস্টম বরাদ্দকারী দ্বারা বরাদ্দকৃত মেমরির মধ্যে একটি শেয়ার্ড_প্টারের ডিলেটর সঞ্চিত আছে?




language-lawyer c++17 (2)

বলুন আমার কাছে একটি কাস্টম বরাদ্দকারী এবং একটি কাস্টম মুছে shared_ptr সাথে একটি শেয়ারড_পিটার রয়েছে।

আমি স্ট্যান্ডার্ডে এমন কিছু খুঁজে পাচ্ছি না যেখানে মুছে ফেলার জায়গাটি কোথায় সংরক্ষণ করা উচিত সে সম্পর্কে কথা বলছে: এটি কাস্টম বরাদ্দকারী মুছে ফেলার স্মৃতির জন্য ব্যবহৃত হবে এবং এটি বলে না যে এটি হবে না

এটি কি অনির্দিষ্ট বা আমি কেবল কিছু মিস করছি?


আমি বিশ্বাস করি এটি অনির্ধারিত।

প্রাসঙ্গিক নির্মাণকারীরা কীভাবে সুনির্দিষ্ট হয় তা এখানে: [util.smartptr.shared.const]/10

template<class Y, class D> shared_ptr(Y* p, D d);
template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
template <class D> shared_ptr(nullptr_t p, D d);
template <class D, class A> shared_ptr(nullptr_t p, D d, A a);

ইফেক্টস: একটি shared_ptr অবজেক্ট তৈরি করে যা অবজেক্ট p এবং মুছে ফেলার মালিক d । যখন T অ্যারে টাইপ নয়, প্রথম এবং দ্বিতীয় কনস্ট্রাক্টরগুলি p shared_from_this সাথে shared_from_this সক্ষম করে। দ্বিতীয় এবং চতুর্থ নির্মাতারা অভ্যন্তরীণ ব্যবহারের জন্য মেমরি বরাদ্দ করতে একটি অনুলিপি ব্যবহার করবেন । যদি একটি ব্যতিক্রম নিক্ষেপ করা হয়, d(p) বলা হয়।

এখন, আমার ব্যাখ্যাটি হ'ল বাস্তবায়নের অভ্যন্তরীণ ব্যবহারের জন্য যখন মেমরির প্রয়োজন হয় তখন এটি ব্যবহার করে এটি ব্যবহার a । এর অর্থ এই নয় যে বাস্তবায়নের সমস্ত কিছু স্থাপনের জন্য এই মেমরিটি ব্যবহার করতে হবে। উদাহরণস্বরূপ, ধরুন যে এই অদ্ভুত বাস্তবায়ন রয়েছে:

template <typename T>
class shared_ptr : /* ... */ {
    // ...
    std::aligned_storage<16> _Small_deleter;
    // ...
public:
    // ...
    template <class _D, class _A>
    shared_ptr(nullptr_t, _D __d, _A __a) // for example
        : _Allocator_base{__a}
    {
        if constexpr (sizeof(_D) <= 16)
            _Construct_at(&_Small_deleter, __d);
        else
            // use 'a' to allocate storage for the deleter
    }
};

এই প্রয়োগটি কি "অভ্যন্তরীণ ব্যবহারের জন্য মেমরি বরাদ্দ করতে একটি অনুলিপি ব্যবহার করে"? হ্যাঁ এটা করে. এটি কখনই ব্যবহার করে স্মৃতি বরাদ্দ করে না। এই নিখুঁত বাস্তবায়নে অনেক সমস্যা রয়েছে, তবে আসুন আমরা বলি যে এটি shared_ptr ব্যবহার করতে স্যুইচ করে তবে shared_ptr কোনও পয়েন্টার থেকে সরাসরি নির্মিত হয় এবং কখনই অনুলিপি করা বা সরানো হয় না বা রেফারেন্স করা হয় এবং অন্য কোনও জটিলতা নেই। মুল বক্তব্যটি হ'ল, আমরা বৈধ বাস্তবায়ন কল্পনা করতে ব্যর্থ হওয়ার অর্থ এই নয় যে এটি তাত্ত্বিকভাবে বিদ্যমান থাকতে পারে। আমি বলছি না যে এরূপ বাস্তবায়ন আসলে পাওয়া যেতে পারে, মানকটি এটি সক্রিয়ভাবে নিষিদ্ধ করছে বলে মনে হয় না।


সি.++ 11 এ ইউজার.সাম্পার্ট.আরশেড.কম / 9:

ইফেক্টস: একটি শেয়ার্ড_পিটার অবজেক্ট তৈরি করে যা অবজেক্ট পি এবং মুছে ফেলার মালিক d। দ্বিতীয় এবং চতুর্থ নির্মাতারা অভ্যন্তরীণ ব্যবহারের জন্য মেমরি বরাদ্দ করতে একটি অনুলিপি ব্যবহার করবেন।

দ্বিতীয় এবং চতুর্থ নির্মাতাদের এই প্রোটোটাইপ রয়েছে:

template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
template<class D, class A> shared_ptr(nullptr_t p, D d, A a);

সর্বশেষ খসড়াটিতে, ব্যবহার.সাম্পার্ট.শায়ারড.কনস্ট / 10 আমাদের উদ্দেশ্যে সমান:

ইফেক্টস: একটি শেয়ার্ড_পিটার অবজেক্ট তৈরি করে যা অবজেক্ট পি এবং মুছে ফেলার মালিক d। যখন টি অ্যারে টাইপ নয়, প্রথম এবং দ্বিতীয় কনস্ট্রাক্টরগুলি পি-র সাথে ভাগ করা_ফ্রম_এটি সক্ষম করে। দ্বিতীয় এবং চতুর্থ নির্মাতারা অভ্যন্তরীণ ব্যবহারের জন্য মেমরি বরাদ্দ করতে একটি অনুলিপি ব্যবহার করবেন। যদি একটি ব্যতিক্রম নিক্ষেপ করা হয়, d (পি) বলা হয়।

সুতরাং বরাদ্দকারী ব্যবহৃত হয় যদি বরাদ্দ মেমরিতে এটি বরাদ্দ করার প্রয়োজন হয়। মানক এবং প্রাসঙ্গিক ত্রুটি প্রতিবেদনগুলির বর্তমান অবস্থার দিকে তাকানো, এটি বাধ্যতামূলক নয় তবে কমিটি মনে করেছে।

  • যদিও shared_ptr ইন্টারফেসটি এমন একটি বাস্তবায়ন করার জন্য ডিজাইন করা হয়েছিল যেখানে কখনই কোনও নিয়ন্ত্রণ ব্লক নেই তবে সমস্ত shared_ptr এবং weak_ptr একটি লিঙ্কযুক্ত তালিকায় রাখা হয়েছিল, weak_ptr এমন কোনও বাস্তবায়ন নেই এবং শব্দটি পরিবর্তিত হয়েছে উদাহরণস্বরূপ ধরে ধরে যে use_count হচ্ছে কিছু ভাগ।

  • মুছে ফেলার জন্য কেবল গঠনমূলক পদক্ষেপ নেওয়া প্রয়োজন। সুতরাং shared_ptr বেশ কয়েকটি অনুলিপি থাকা সম্ভব নয়।

এটি এমন একটি বাস্তবায়ন কল্পনা করা সম্ভব হবে যা মুছে ফেলা একটি বিশেষ shared_ptr এবং সরানো হয় যখন এটি বিশেষ shared_ptr মুছে ফেলা হয় তবে এটি যথাযথভাবে অদ্ভুত হবে, বিশেষত ব্যবহারের গণনার জন্য একটি নিয়ন্ত্রণ ব্লক সম্ভবত প্রয়োজন (এটি এটি সম্ভবত সম্ভব তবে ব্যবহার গণনা সহ একই জিনিসটি করতে অযৌক্তিক)।

প্রাসঙ্গিক ডিআরএস আমি পেয়েছি: 545 , 575 , 2434 (যা স্বীকৃতি দেয় যে সমস্ত বাস্তবায়ন একটি নিয়ন্ত্রণ ব্লক ব্যবহার করছে এবং এটি বোঝায় যে মাল্টি-থ্রেডিং সীমাবদ্ধতা কিছুটা এটিকে নির্দেশ দেয়), 2802 (যা মুছে ফেলার উপর প্রয়োজনীয়তাকে কেবল গঠনমূলক পদক্ষেপে নিয়ে যায় এবং এইভাবে প্রতিরোধ করে বাস্তবায়ন যেখানে মুছে shared_ptr বেশ কয়েকটি shared_ptr মধ্যে অনুলিপি করা হয়)।







allocator