加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

重载运算符new / new []删除/删除[]全局C

发布时间:2020-12-16 06:53:36 所属栏目:百科 来源:网络整理
导读:我有这个示例代码用于重载operator new和delete #include iostream#include cstddef#include new#ifdef USE_ZMALLOCextern "C" {#include "zmalloc.h"}#define m_malloc zmalloc#define m_free zfree#else#ifdef USE_JEMALLOC#include jemalloc/jemalloc.h#d
我有这个示例代码用于重载operator new和delete

#include <iostream>
#include <cstddef>
#include <new>

#ifdef USE_ZMALLOC
extern "C" {
#include "zmalloc.h"
}
#define m_malloc zmalloc
#define m_free zfree
#else
#ifdef USE_JEMALLOC
#include <jemalloc/jemalloc.h>
#define m_malloc je_malloc
#define m_free je_free
#else
#include "malloc.h"
#define m_malloc std::malloc
#define m_free std::free
#endif
#endif

// C++ requires that operator new return a legitimate pointer
//  even when zero bytes are requested. That's why if (size == 0) size = 1
void* operator new (std::size_t size) throw (std::bad_alloc) {
  using namespace std;
  if (size == 0) { // Handle 0-byte requests by treating them as 1-byte requests
    size = 1;
  }

  while (true) {
    void* mem = m_malloc(size);

    if (mem != nullptr) {
      return mem;
    } 

    new_handler global_handler = set_new_handler(nullptr);
    set_new_handler(global_handler);

    if (global_handler) {
      (*global_handler)();
    } else {
      throw bad_alloc();
    }

  }
}

void* operator new[] (std::size_t size) throw (std::bad_alloc) {
  return operator new(size);
}

void operator delete (void* ptr) throw() {
  if (ptr == nullptr) {
    return;
  }

  m_free(ptr);
}

void operator delete[] (void* ptr) throw() {
  operator delete(ptr);
}

这段代码实际上正常工作,一切似乎都是正确的.
我的问题是:当使用valgrind时,如果我这样做:

int main() {
  Foo** foo = new Foo*[10];

  std::cout << "# " << zmalloc_used_memory() << "." << std::endl;

  delete foo;  // Using wrong delete operator

  return 0;
}

valgrind不会抱怨使用错误的运算符删除.
如果我使用默认运算符new / delete对,valgrind会警告我操作符删除错误.

1)我的新/删除操作符有问题吗?
2)valgrind不再警告这种错误,这是正常的吗?

谢谢!

解决方法

首先,这些不是过载(因为它们具有完全相同的原型).这些都是替代品.

最有可能的问题是Valgrind并不知道你已经取代了这些全球操作符.如果你在共享库中进行替换,Valgrind将会看到函数和原型,并且能够挂钩它们.但是,如果替换是在您的可执行文件中,您将需要告诉Valgrind.我认为这可以通过检测代码来实现,但这非常困难.更简单的方法是使用Valgrind选项–soname-synonyms = somalloc = NONE.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读