[英]overload operators new/new[] delete/delete[] globally C++
我有這個用於重載運算符 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 不會抱怨使用了錯誤的操作符 delete。 如果我使用默認的操作符 new/delete 對,valgrind 會警告我操作符刪除錯誤。
1)我的新/刪除操作員有問題嗎?
2) valgrind 不再警告此類錯誤是否正常?
謝謝!
首先,這些不是重載(因為它們具有完全相同的原型)。 這些是替代品。
最有可能的問題是 Valgrind 不知道您已經替換了這些全局運算符。 如果您在共享庫中進行替換,Valgrind 將看到函數和原型,並且能夠掛鈎它們。 但是,如果替換是在您的可執行文件本身中,您需要告訴 Valgrind。 我認為這可以通過檢測代碼來實現,但這非常困難。 更簡單的方法是使用 Valgrind 選項 --soname-synonyms=somalloc=NONE 。
更新:我不確定 OP 使用的是哪個版本的 Valgrind,但自 Valgrind 3.12.0(2016 年 10 月 20 日)以來,您不需要任何選項來檢測用戶更換 malloc/new。
我使用 Valgrind 3.20.0(來自 git HEAD,2022 年 6 月)得到的輸出是
==5989== Mismatched free() / delete / delete []
==5989== at 0x4030741: operator delete(void*, unsigned long) (vg_replace_malloc.c:947)
==5989== by 0x4012D9: main (in /home/pafloyd/scratch/vg_examples/so_replace_new/srn)
==5989== Address 0x5328c80 is 0 bytes inside a block of size 80 alloc'd
==5989== at 0x402F103: operator new[](unsigned long) (vg_replace_malloc.c:652)
==5989== by 0x4012BF: main (in /home/pafloyd/scratch/vg_examples/so_replace_new/srn)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.