delete不会将0分配给指针 在C或C++中,当我们删除某个指针时,它只释放内存,但不将指针设置为0。由于我们无法检查指针的有效性,因此如果在释放内存后将指针设置为0,程序员将更容易检查指针的空值
我只是想知道为什么实现“delete”只是为了释放内存 > P>因为C++中几乎都是关于性能的。您不希望编译器添加代码,您不需要。您不希望您的程序做一些事情,因为您没有在代码中添加它们 如果您确定on one将检查/重用此指针,则无需取消。少一条指令 另外,如果删除指针,将其设置为delete不会将0分配给指针 在C或C++中,当我们删除某个指针时,它只释放内存,但不将指针设置为0。由于我们无法检查指针的有效性,因此如果在释放内存后将指针设置为0,程序员将更容易检查指针的空值,c++,c,C++,C,我只是想知道为什么实现“delete”只是为了释放内存 > P>因为C++中几乎都是关于性能的。您不希望编译器添加代码,您不需要。您不希望您的程序做一些事情,因为您没有在代码中添加它们 如果您确定on one将检查/重用此指针,则无需取消。少一条指令 另外,如果删除指针,将其设置为NULL,那么指向已删除内存的其他指针会发生什么情况?它们不会被废除。这可能会导致糟糕的事情 < P>只要需要,就分配 null 。< /p> ,因为在C++中,几乎所有的性能都是。您不希望编译器添加代码,您不需要。您
NULL
,那么指向已删除内存的其他指针会发生什么情况?它们不会被废除。这可能会导致糟糕的事情
< P>只要需要,就分配<代码> null <代码>。< /p> ,因为在C++中,几乎所有的性能都是。您不希望编译器添加代码,您不需要。您不希望您的程序做一些事情,因为您没有在代码中添加它们
如果您确定on one将检查/重用此指针,则无需取消。少一条指令
另外,如果删除指针,将其设置为NULL
,那么指向已删除内存的其他指针会发生什么情况?它们不会被废除。这可能会导致糟糕的事情
如果需要,只需分配NULL
由于我们无法检查指针的有效性,如果释放内存后将指针设置为0,程序员将更容易检查指针的空值
检查nullvalue可能会隐藏错误,同时增加代码大小和复杂性,并产生错误的安全感。不能保证指针值(在为零之前)没有被复制到其他地方。此外,这还可以防止按值删除,这是错误地提供空值删除操作的库(如OpenCV)的主要麻烦
与这种适得其反的做法相反,使用确保正确清理和防止无效指针的技术,例如使用适当的智能指针
由于我们无法检查指针的有效性,如果释放内存后将指针设置为0,程序员将更容易检查指针的空值
检查nullvalue可能会隐藏错误,同时增加代码大小和复杂性,并产生错误的安全感。不能保证指针值(在为零之前)没有被复制到其他地方。此外,这还可以防止按值删除,这是错误地提供空值删除操作的库(如OpenCV)的主要麻烦
与这种适得其反的做法相反,请使用确保正确清理和防止无效指针的技术,例如使用适当的智能指针。没有必要:因为您只在SBRM包装类的析构函数中删除了
,因此以后没有任何其他方法可以访问指针:
template <typename T> struct MyPtr
{
template <typename ...Args> MyPtr(Args &&... args)
: p(new T(std::forward<Args>(args)...)
{ }
~MyPtr()
{
delete p; // done! who cares what `p` is now.
}
MyPtr(MyPtr const &) = delete;
MyPtr & operator=(MyPtr const &) = delete;
T * operator->() { return p; }
private:
T * p;
}
模板结构MyPtr
{
模板MyPtr(Args&…Args)
:p(新T(标准::转发(参数)…)
{ }
~MyPtr()
{
删除p;//完成!谁在乎现在的“p”是什么。
}
MyPtr(MyPtr const&)=删除;
MyPtr&运算符=(MyPtr const&)=删除;
T*运算符->(){return p;}
私人:
T*p;
}
没有必要:因为您只在SBRM包装器类的析构函数中删除了,所以以后没有其他东西可以访问指针:
template <typename T> struct MyPtr
{
template <typename ...Args> MyPtr(Args &&... args)
: p(new T(std::forward<Args>(args)...)
{ }
~MyPtr()
{
delete p; // done! who cares what `p` is now.
}
MyPtr(MyPtr const &) = delete;
MyPtr & operator=(MyPtr const &) = delete;
T * operator->() { return p; }
private:
T * p;
}
模板结构MyPtr
{
模板MyPtr(Args&…Args)
:p(新T(标准::转发(参数)…)
{ }
~MyPtr()
{
删除p;//完成!谁在乎现在的“p”是什么。
}
MyPtr(MyPtr const&)=删除;
MyPtr&运算符=(MyPtr const&)=删除;
T*运算符->(){return p;}
私人:
T*p;
}
即使删除将NULL分配给指针,也不会使任何事情变得更安全。因为多个指针可以指向同一内存地址,将NULL分配给其中一个不会使其他指针也为NULL。即使删除将NULL分配给指针,也不会使任何事情变得更安全。因为多个poiNTER可以指向相同的内存地址,将NULL分配给其中一个不会使其他变量也为NULL。您可以删除常量指针变量。将其设置为NULL是不可能的,只有在删除后将可变指针变量设置为NULL似乎有点不一致。您可以删除常量指针变量。将其设置为NULL是不可能的,只有在删除后将可变指针变量设置为NULL似乎有点不一致。首先,出于效率原因,您可能希望在删除后执行指针算术:
const int SIZE = 5;
MyObject* foo[SIZE];
// ... initialize foo with new MyObjects...
for (MyObject* i = &foo[0], end = &foo[0] + SIZE; i < end; ++i)
{
delete i;
}
const int SIZE=5;
MyObject*foo[大小];
//…使用新的MyObject初始化foo。。。
对于(MyObject*i=&foo[0],end=&foo[0]+SIZE;i
首先,出于效率原因,您可能希望在删除后执行指针算术:
const int SIZE = 5;
MyObject* foo[SIZE];
// ... initialize foo with new MyObjects...
for (MyObject* i = &foo[0], end = &foo[0] + SIZE; i < end; ++i)
{
delete i;
}
const int SIZE=5;
MyObject*foo[大小];
//…使用新的MyObject初始化foo。。。
对于(MyObject*i=&foo[0],end=&foo[0]+SIZE;i
删除后只需将其设置为NULL。另外,许多人将其作为一种编码标准,即在删除某些内容后,立即手动将指针设置为0。删除将指针设置为NULL会产生错误的安全感,很可能有其他指针指向同一内存块。要添加到@Joac点Himisakson提出,一个很好的例子是,如果在函数中执行删除,而不将指针作为引用或双指针传递,只需将其设置为NULL