我想实现类似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();
其中name
是string
,而temp
是stringstream
。我尝试在非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
的范围缩小到我完全管理自己的对象?
答案 0 :(得分:0)
除new()
和delete()
外,还有new[]()
和delete[]()
个运营商。例如,当new()[]
运算符用于分配数组,然后delete()
用于解除分配时,标准库中存在一些不一致。如果您没有超载所有四个运算符,这些不一致可能会导致内存分配错误。请注意,在C ++ 17中,它将是更多新的/删除操作符。