0

Visual Studioヘッダーで、voidへのポインターを介してメモリが解放される場所をいくつか見つけました。

xlocnumファイル:

template<class _Elem>
     class numpunct
            : public locale::facet
    { 
     _PROTECTED:
     _VIRTUAL __CLR_OR_THIS_CALL ~numpunct()
     {       // destroy the object
         _Tidy();
     }
     ...
     protected:
        void __CLR_OR_THIS_CALL _Init(const _Locinfo& _Lobj)
        {       // initialize from _Lobj
            _Grouping = 0;
            _Falsename = 0;
            _Truename = 0;

            _TRY_BEGIN
            _Grouping = _MAKLOCSTR(char, _Ptr->grouping, _Lobj._Getcvt());
            _Falsename = _MAKLOCSTR(_Elem, _Lobj._Getfalse(), _Lobj._Getcvt());
            _Truename = _MAKLOCSTR(_Elem, _Lobj._Gettrue(), _Lobj._Getcvt());
            _CATCH_ALL
            _Tidy();
            _RERAISE;
            _CATCH_END
             ...
            }
      ...
      private:
      void __CLR_OR_THIS_CALL _Tidy()
      {       // free all storage
         _DELETE_CRT_VEC((void *)_Grouping);
         _DELETE_CRT_VEC((void *)_Falsename);
         _DELETE_CRT_VEC((void *)_Truename);
      }
    ... 
    const char *_Grouping;  // grouping string, "" for "C" locale
    const _Elem *_Falsename;// name for false, "false" for "C" locale
    const _Elem *_Truename; // name for true, "true" for "C" locale
    };

またはxlocaleの別の1つの例:

template<> class _CRTIMP2_PURE ctype<char>
    : public ctype_base
    {
       public:
          explicit __CLR_OR_THIS_CALL ctype(const mask *_Table = 0,
              bool _Deletetable = false,
              size_t _Refs = 0)
              : ctype_base(_Refs)
                {       // construct with specified table and delete flag for table
                   ...
                   if (_Table != 0)
                   {       // replace existing char to mask table
                       _Tidy();
                       _Ctype._Table = _Table;
                       _Ctype._Delfl = _Deletetable ? -1 : 0;
                   }
                }
        protected:
           void __CLR_OR_THIS_CALL _Tidy()
           {       // free any allocated storage
              if (0 < _Ctype._Delfl)
                   free((void *)_Ctype._Table);
              else if (_Ctype._Delfl < 0)
                    delete[] (void *)_Ctype._Table;
            }
    }

https://stackoverflow.com/a/941959/1549256で指摘されているように、voidポインターを介した削除は、C++標準では定義されていません。

そのような場合にメモリを解放するのはなぜ正しいのですか?

4

2 に答える 2

4

The code in the standard library implementation does not have to conform to the language definition. It can take advantage of knowledge of the implementation; that's why it comes with the compiler.

于 2012-12-02T13:12:52.837 に答える
1

未定義は、それが機能しないことを意味するのではなく、実装が正常に機能することを含め、必要なことを自由に実行できることを意味します。

キャストポインタを削除する際に考えられる問題の1つは、デストラクタが呼び出されない可能性があることですが、削除時に元に戻す必要のあるコンストラクタがないタイプの場合、これは問題にならない可能性があります。

于 2012-12-02T13:05:24.890 に答える