有没有办法全局填充新/删除分配?

时间:2017-01-27 19:54:36

标签: c++ malloc new-operator free delete-operator

我想实现类似this的东西,其中在Java堆上分配本机内存。为了实现这一点,我需要这部分代码才能工作:

const static int pad = 16;
void * operator new(size_t t) throw(std::bad_alloc) {
    void* padded = malloc((int) t + pad);
    void* p = static_cast<void *>(static_cast<char *>(padded) + pad);
    std::cout << "new: " << p << " padded " << padded << " size: " << t << std::endl;
    return p;
}

void operator delete(void *p) throw() {
   if (p != 0) {
    void *padded = static_cast<void *>(static_cast<char *>(p) - pad);
    std::cout << "del: " << p << " padded " << padded << std::endl;
    free(padded);
  } else {
    std::cout << "pointer is zero!" << std::endl;
 }
}

我正在尝试做的是为每个内存分配添加一些字节。这似乎工作正常(大多数删除都是成功的),但我收到一个错误:

java(379,0x700002206000) malloc: *** error for object 0x7fc104122180: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

堆栈跟踪指示从此行立即调用free(即,不是我的delete):

name = temp.str();

其中namestring,而tempstringstream。我尝试在非JNI上下文中重现此错误,但它没有在那里崩溃。

如果我像这样填充内存,那么显然free通过new分配的东西或delete直接分配的东西是错误的malloc。这有可能吗?

在我的标准输出中搜索错误中的地址支持:

new: 0x7fc104122190 padded 0x7fc104122180 size: 32
del: 0x7fc104122190 padded 0x7fc104122180
new: 0x7fc104122180 padded 0x7fc104122170 size: 32

看起来地址已成功分配然后解除分配。同一地址再次出现在打印到stdout的最后一行中的未填充地址(我认为这个地址最终成为第二次分配中的未填充地址)。但由于这是打印到std的最后一行,因此free尝试失败并未通过我看到的代码(即使我自己覆盖free)。

是否可以采用这种方法?或者我是否必须将new / delete的范围缩小到我完全管理自己的对象?

1 个答案:

答案 0 :(得分:0)

new()delete()外,还有new[]()delete[]()个运营商。例如,当new()[]运算符用于分配数组,然后delete()用于解除分配时,标准库中存在一些不一致。如果您没有超载所有四个运算符,这些不一致可能会导致内存分配错误。请注意,在C ++ 17中,它将是更多新的/删除操作符。