4

我遇到了以下代码:

    class a {
    public:

        void *  operator new(size_t l, int nb);
        double  values;
    };
void *a::operator new (size_t l,int n)
{
    return new char[l+ (n>1 ? n - 1 : 0)*sizeof(double)];
}

从我得到的结果来看,它被用来拥有一个从“值”开始的类似数组的结构:

double* Val = &(p->a->values) + fColumnNumber;

我的问题是:是否存在内存泄漏?我对重载 new 运算符非常陌生,但我很确定分配的内存没有正确释放。这是否也意味着我永远不能在堆栈上创建一个“a”类?

谢谢

4

5 回答 5

5

我相信它在技术上会按原样产生 UB,尽管它是一种可能永远不会引起可见副作用的 UB(它正在使用new [],但我相信会与之匹配delete——但是对于char,这通常不会导致一个明显的问题)。

IMO,它使用新表达式来分配真正应该是原始字节而不是对象的内容几乎更糟糕。如果我这样做,我会这样写:

void *a::operator new (size_t l,int n)
{
    return ::operator new(l+ (n>1 ? n - 1 : 0)*sizeof(double));
}

您可以将其与:

void a::operator delete(void *block)
{
    ::operator delete(block);
}
于 2012-05-11T14:29:04.580 回答
1

我不明白为什么operator delete在 an 上调用的默认值a *无法正确释放此 custom 分配的内存operator new。最好的检查方法是实际编写一些代码并找出答案,尽管我可能会在 valgrind 等分析器中运行它而不是 rob05c 的技术。我假设提问者看到发生了内存泄漏并怀疑这是原因,所以围绕这个运算符编写一个测试用例似乎是一项值得的努力。

显然,如果之后没有人真正删除它,它就会泄漏......

我会质疑覆盖new这种功能的必要性,但我也认为这是其他人的代码。

于 2012-05-11T14:12:08.457 回答
0

它很好,但你需要在使用这个类的代码中使用delete[],而不是delete,因为它分配了一个数组。请注意,用户不会得到他们需要这样做的任何提示 - 因此为他们重载删除运算符将是一个好主意。

于 2012-05-11T14:19:55.093 回答
0
  1. 您绝对可以在堆栈上创建类“a”。
  2. 您应该知道 4 个(实际上更多,但会坚持基础)新的和删除的方法签名。

    void* operator new (std::size_t size) throw (std::bad_alloc);
    void* operator new[] (std::size_t size) throw (std::bad_alloc);
    void operator delete (void* ptr) throw ();
    void operator delete[] (void* ptr) throw ();
    

    您正在“operator new”方法中分配一个数组,这应该在“operator new[]”方法中完成。这将摆脱你讨厌的检查。写两个,“operator new”和“operator new[]”

  3. 不要忘记你想给调用者一个“a”类型的对象(a myA = new a)所以确保你返回“a”而不是char*,因此你也需要进行强制转换。

  4. 你需要编写相应的delete[]和delete方法。

  5. 要回答您的问题,我相信它确实会泄漏内存。您提供的新签名称为“新位置”。这允许您在不分配内存的情况下分配新指针,而是给它一个指向的位置。示例:如果您需要指向内存中特定点的指针。

    long z = 0x0F9877F80078;
    a myA = new (z) a[5];  // 5 pointers that point to 0x0F9877F80078
    

根据定义,placement-new 运算符不应该分配内存,因为你有你让你泄漏。摆脱你的第二个参数,你现在可以这样做,因为你有两个版本的 operator new 并且你很高兴。不要忘记返回一个对象“a”。

查看 IBM 的信息中心: http: //publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp ?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr318.htm

以及参考资料,cpluplus.com: http ://www.cplusplus.com/reference/std/new

于 2012-05-11T15:05:03.447 回答
0

这很容易找到。编写一个构造和解构大量 a 的循环并观察您的内存使用情况。如果它泄漏,它会很快上升。

于 2012-05-11T14:08:40.097 回答