删除以前删除的内存
Deleting memory when it was deleted before
我有一个小型C++程序,在其中我创建了一个Person
类的两个对象。此类具有用于数据的char *m_szFirstName
和char *m_szLastName
。
然后,我将一个对象分配给另一个对象,使两个对象的数据成员指向同一位置
在析构函数中,我删除为第一个对象分配的内存,并为指针分配NULL
值。像这样的东西。
if (m_szFirstName!= NULL)
{
delete [] m_szFirstName;
m_szFirstName = NULL;
}
然后,当我去删除第二个对象的内存时,对NULL
的检查不起作用,当我删除内存时,我会崩溃。从调试器中,它显示我的指针不是NULL
。它具有0xfeee
。
我知道以前已经删除了内存,不应该删除。然而,我不知道如何检查是否应该删除内存。
崩溃原因:
您应该遵循三规则来避免悬挂指针的问题。
如果您需要自己显式声明析构函数、复制构造函数或复制赋值运算符,则可能需要显式声明这三个运算符。
在您的情况下,您没有定义复制赋值运算符,从而导致指针的浅层复制。
建议的解决方案:
如果您可以使用std::string
而不是char *
,只需简单地使用std::string
,它就比任何愚蠢的指针内容都具有首要的偏好
使用std::string
可以避免所有时髦的指针。
如果你读不下去,下面的建议通常适用于任何类指针成员。
请注意,这里的理想解决方案是根本不使用原始指针。无论何时使用原始指针,都必须手动管理它们获取的资源,手动管理资源总是很困难且容易出错。因此,我们有责任避免这种情况
为此,您应该使用智能指针,它将隐式管理指针的动态内存。使用智能指针将确保动态存储器在使用后被隐式释放&你不必手动管理它。
您所拥有的场景正是在C++中您应该依赖RAII而不是手动资源管理的原因;在您的情况下,使用智能指针是一种可行的方法。
注意事项:
请注意,我克制自己,不建议使用哪个智能指针,因为选择取决于所涉及元素的所有权和寿命,这从问题中提供的数据中并不清楚。因此,我建议阅读,
何时使用哪种指针?
选择要使用的智能指针。
使用
if (m_szFirstName!= NULL)
{
delete [] m_szFirstName;
m_szFirstName = NULL;
}
仅将m_szFirstName设置为指向NULL,而不是m_szLastName。这意味着你必须有一些方法来跟踪它们指向同一位置的事实。他们指向同一地点有什么原因吗?你能复制这个名字而不是把指针指向同一个地方吗?
如果你需要两个指针来共享相同的数据,我会看看std::tr1::shared_ptr,它将通过跟踪引用的数量并在引用数量达到0时删除来为你解决这个问题。
如果(m_szFirstName==m_szLastName),则不要再次删除它。但这会导致内存泄漏(当您将一个指针分配给另一个指针时)。
当有两个指针指向同一位置时(在将第一个指针分配给第二个之后),就有两个指向同一地址的指针。删除一个会释放它们所指向的内存。但将其中一个指针设置为NULL
不会改变另一个指针。例如,如果有两个整数,也会发生同样的情况。
int a = 3;
int b = a;
现在,如果你运行
a = 0;
CCD_ 13的值不变。同样,当你改变第一个指针时,你的第二个指针不会改变(但当你改变其中一个指针指向的内存时,你也可以通过另一个指针看到效果)。
您的问题是一个经典的C/C++问题,即所谓的"挂起指针"问题。取消对悬挂指针的引用导致了崩溃。问题是关于引用计数。一旦将相同的内存分配给第二个指针,则引用计数应为2。因此,如果删除一个指针,则引用计数应变为1,并且除非计数为0,否则不应解除分配或释放内存。在0时可以进行垃圾收集。
现在,上面有很好的答案可以解决你的问题。由于您使用的是C++,所以您可以使用类似auto_ptr(OR shared_ptr)的东西。它们提供了我上面提到的,引用计数的东西,即使你不必担心删除或释放你的对象,这些类也会很好。他们在被称为RAII模式的simething上工作,当堆栈上的对象超出范围时,析构函数会被自动神奇地调用。
删除对象后,只需停止将指针设置为NULL即可。正如你所看到的,这只会导致疼痛。您不能认为因为指针不是NULL,所以它还没有被删除。
您可以使用任何合理的模式来避免这个问题。例如,Boost的shared_ptr
就是一个不错的选择。
- 在c++中删除内存失败
- delete[]有问题,如何部分删除内存
- 在这种情况下,我必须删除内存吗?
- STD分配器是否会在堆上动态分配内存?它可以安全地删除内存吗?
- 我可以在使用 winsoc 发送缓冲区后删除内存吗?
- 最好的方法是删除内存泄漏
- com,删除内存,而不是调用版本()
- 如何调用返回后删除[]内存
- 删除内存空间后,指针的值保持不变还是更改?对象内容是否将被更改
- unique_ptr的矢量未被完全删除(内存泄漏)
- 在析构函数中安全地删除内存
- (C++) list.error 方法和使用指针删除内存
- 为结构C++中的指针分配和删除内存
- 正在读取指向已删除内存未定义行为的指针
- 何时会在单一实例中删除内存
- 删除内存时遇到困难
- 在 go 中删除内存
- 在C++中使用智能指针分配和删除内存的有效方法
- Cpp删除内存
- 手动调用析构函数后如何删除内存