【问题标题】:Operator delete causing heap corruption while operator new working fine操作员删除导致堆损坏,而操作员新的工作正常
【发布时间】:2010-11-27 06:53:11
【问题描述】:

我已经让 operator new 工作,但是一旦我调用 delete,它就会在 free (ptr) 行崩溃。在这个基类中重载 operator new 和 delete 时,谁能告诉我做错了什么?提示:我不是在问设计问题。

class Base {
private: 
    int i;

public:  
    Base () : i (10) {
    }

    static void * operator new (size_t size) {  
       if (size = 0) size = 1;  // please read this line carefully! size = 0!
       return malloc (size);  
    }

    static void operator delete (void *ptr, size_t size) {
       if (ptr == NULL) return;
       free (ptr);
    }
};

【问题讨论】:

  • 您是要删除一个对象两次,还是通过调用new未获得的指针删除一个对象?
  • 附带说明,free(NULL) 保证是安全的(无操作),因此您不必对其进行特殊处理。
  • hm...我的错:如果将 if (size==0) 替换为 if (size=0) 并添加私有数据成员以及构造函数,则代码将失败。我知道size=0 是一个不应该发生的错误,但只有当您在构造函数中初始化此类的私有数据成员时,代码才会失败。

标签: c++ new-operator


【解决方案1】:

这对我有用:

#include <cstdlib>
using namespace std;
class Base {
public:
    void * operator new(size_t size) {
       if (size == 0) size = 1;
       return malloc (size);
    }

    void operator delete (void *ptr, size_t size) {
       if (ptr == NULL) return;
       free (ptr);
    }
};

int main()
{
    Base* b = new Base;
    delete b;
    return 0;
}

hank@tardis:/tmp$ g++ -o test test.cpp 
hank@tardis:/tmp$ ./test 
hank@tardis:/tmp$ valgrind ./test 
==7229== HEAP SUMMARY:
==7229==     in use at exit: 0 bytes in 0 blocks
==7229==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==7229== 
==7229== All heap blocks were freed -- no leaks are possible
==7229== 
==7229== For counts of detected and suppressed errors, rerun with: -v
==7229== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

【讨论】:

  • 谢谢。是的,你的代码很好。我对我的代码做了一些进一步的更改。你能对此发表评论吗?
【解决方案2】:

实际问题既不是new 也不是delete 运算符。您对它们的实现非常简单,这里没有问题。

您遇到的实际问题是堆损坏。这是由您的代码引起的,不一定是操作Base 对象的代码。 只是当您 delete 您的对象时,才发现堆损坏。

可能你有一些代码在你delete你的对象之前进行堆损坏。

您应该检查您的代码是否存在无效的内存访问。这包括:

  1. 确保您访问的内存不会超过分配的内存
  2. 确保在释放内存后不要使用它。

【讨论】:

    【解决方案3】:

    我认为您提供的示例代码没有任何问题。

    以下内容对我来说很好。

    prasoon@prasoon-desktop ~ $ cat leak_check.cpp && g++ leak_check.cpp && valgrind --leak-check=full ./a.out
    #include <cstdlib>
    class Base {
    public:
        static void * operator new (size_t size) {
           if (size == 0) size = 1;
           return malloc (size);
        }
    
        static void operator delete (void *ptr, size_t size) {
           if (ptr == NULL) return;
           free (ptr);
        }
    };
    
    int main()
    {
       Base * p = (Base *) Base::operator new(sizeof(Base));
       Base::operator delete((void*)p,sizeof(Base));
    }
    ==4561== Memcheck, a memory error detector
    ==4561== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==4561== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==4561== Command: ./a.out
    ==4561== 
    ==4561== 
    ==4561== HEAP SUMMARY:
    ==4561==     in use at exit: 0 bytes in 0 blocks
    ==4561==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated
    ==4561== 
    ==4561== All heap blocks were freed -- no leaks are possible
    ==4561== 
    ==4561== For counts of detected and suppressed errors, rerun with: -v
    ==4561== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6)
    

    顺便说一句,释放空指针非常好。

    free 函数使ptr 指向的空间被释放,也就是说,可用于进一步分配。如果ptr 是空指针,不会发生任何操作

    所以if (ptr == NULL) return; 可以省略。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      • 2013-02-07
      相关资源
      最近更新 更多