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这不是一个好主意,不是你在C++中会做的事情。您正在无缘无故地丢失您的类型信息 当为非基元类型调用析构函数时,将不会对要删除的数组中的对象调用析构函数 您应该替代新建/删除。 删除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);
}