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 中的另一个示例:

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

标准库实现中的代码不必符合语言定义。它可以利用实施知识;这就是编译器附带它的原因。

于 2012-12-02T13:12:52.837 回答
1

未定义并不意味着它不会工作,它只是意味着一个实现可以自由地做任何它想做的事情,包括工作正常。

删除强制转换指针的一个可能问题是可能不会调用析构函数,但如果类型是没有需要在删除时反转的构造函数的类型,这可能不是问题。

于 2012-12-02T13:05:24.890 回答