C++ 删除空指针是否安全?

C++ 删除空指针是否安全?,c++,memory-management,casting,void-pointers,C++,Memory Management,Casting,Void Pointers,假设我有以下代码: void* my_alloc (size_t size) { return new char [size]; } void my_free (void* ptr) { delete [] ptr; } 这安全吗?或者必须将代码> PTR 转换为 char */COD>删除之前? 这不是一个好主意,不是C++中的一个好主意。您正在无缘无故地丢失您的类型信息 当为非基元类型调用析构函数时,将不会对要删除的数组中的对象调用析构函数 您应该替代新建/删除。 删除voi

假设我有以下代码:

void* my_alloc (size_t size)
{
   return new char [size];
}

void my_free (void* ptr)
{
   delete [] ptr;
}

这安全吗?或者必须将代码> PTR <代码>转换为<代码> char */COD>删除之前?

这不是一个好主意,不是C++中的一个好主意。您正在无缘无故地丢失您的类型信息

当为非基元类型调用析构函数时,将不会对要删除的数组中的对象调用析构函数

您应该替代新建/删除。

删除void*可能会碰巧正确地释放内存,但这是错误的,因为结果未定义


如果由于我不知道的原因,您需要将指针存储在一个空*中,然后释放它,您应该使用malloc和free 当为非基元类型调用析构函数时,将不会对要删除的数组中的对象调用析构函数

您应该替代新建/删除。

删除void*可能会碰巧正确地释放内存,但这是错误的,因为结果未定义


如果由于我不知道的原因,您需要将指针存储在一个空*中,然后释放它,您应该使用malloc和free

删除空指针是危险的,因为不会对它实际指向的值调用析构函数。这可能会导致应用程序内存/资源泄漏

删除空指针是危险的,因为不会对它实际指向的值调用析构函数。这可能会导致应用程序内存/资源泄漏

因为char没有特殊的析构函数逻辑。这行不通

class foo
{
   ~foo() { printf("huzza"); }
}

main()
{
   foo * myFoo = new foo();
   delete ((void*)foo);
}

不会调用d'ctor。

因为char没有特殊的析构函数逻辑。这行不通

class foo
{
   ~foo() { printf("huzza"); }
}

main()
{
   foo * myFoo = new foo();
   delete ((void*)foo);
}

d'ctor不会被调用。

很多人已经评论说,不,删除空指针是不安全的。我同意这一点,但我还想补充一点,如果您使用void指针来分配连续数组或类似的东西,那么您可以使用
new
来实现这一点,这样您就可以安全地使用
delete
(嗯,需要一些额外的工作)。这是通过分配一个指向内存区域(称为“竞技场”)的空指针,然后将指向竞技场的指针提供给新的内存区域来实现的。请参阅中的本节。这是一个在C++中实现内存池的常用方法。

很多人已经说过,不,删除空指针是不安全的。我同意这一点,但我还想补充一点,如果您使用void指针来分配连续数组或类似的东西,那么您可以使用

new
来实现这一点,这样您就可以安全地使用
delete
(嗯,需要一些额外的工作)。这是通过分配一个指向内存区域(称为“竞技场”)的空指针,然后将指向竞技场的指针提供给新的内存区域来实现的。请参阅中的本节。这是一个在C++中实现内存池的常用方法。

< P>它依赖于“Surfy”。它通常会工作,因为信息与指针本身存储在分配本身上,所以DealLoopor可以将它返回到正确的位置。从这个意义上讲,只要分配器使用内部边界标记,它就是“安全的”。(很多人是这样做的。)

但是,正如其他答案中提到的,删除空指针不会调用析构函数,这可能是一个问题。从这个意义上讲,它不是“安全的”


没有充分的理由按照你现在的方式去做你正在做的事情。如果要编写自己的释放函数,可以使用函数模板生成具有正确类型的函数。这样做的一个很好的理由是生成池分配器,这对于特定类型来说非常有效

其他答案中提到的,这是C++语言。一般来说,避免未定义的行为是很好的,尽管主题本身很复杂,充满了相互冲突的观点。

这取决于“安全”。它通常会起作用,因为有关分配本身的信息与指针一起存储,所以deallocator可以将其返回到正确的位置。从这个意义上讲,只要分配器使用内部边界标记,它就是“安全的”。(很多人是这样做的。)

但是,正如其他答案中提到的,删除空指针不会调用析构函数,这可能是一个问题。从这个意义上讲,它不是“安全的”


没有充分的理由按照你现在的方式去做你正在做的事情。如果要编写自己的释放函数,可以使用函数模板生成具有正确类型的函数。这样做的一个很好的理由是生成池分配器,这对于特定类型来说非常有效


其他答案中提到的,这是C++语言。一般来说,避免不明确的行为是很好的,虽然主题本身是复杂的,并且充满了相互矛盾的观点。

< P>删除空指针是由C++标准定义的——参见5.3.5/3节:< /P> 在第一个备选方案中(删除 对象),如果 操作数与它的动态 类型,静态类型应为底座 操作数的动态类型的类 静态类型应具有 虚拟析构函数或行为为 未定义。在第二种选择中 (删除数组)如果 要删除的对象不同于 它的静态类型,行为是 未定义

及其脚注:

这意味着一个对象不能被复制 使用void类型的指针删除* 因为没有类型为的对象 空虚


<> > /P> < P>删除空指针是由C++标准定义的——参见5.3.5/3节:< /P> 在第一个备选方案中(删除 对象),如果 操作数与它的动态 类型,静态类型应为底座 操作数的动态类型的类 还有stati
template<int size_ > struct size_buffer { 
  char data_[ size_]; 
  operator void*() { return (void*)&data_; }
};

typedef sized_buffer<100> OpaqueBuffer; // logical description of your sized buffer

OpaqueBuffer* ptr = new OpaqueBuffer();

delete ptr;
void* my_alloc (size_t size)
{
   return ::operator new(size);
}

void my_free (void* ptr)
{
   ::operator delete(ptr);
}