这个问题已经存在一年了,但我们遇到了同样的问题并找到了这个帖子。我们可以使用以下 C 代码在 Mac 上的最新 Xcode 7.3 中简化和重现它:
int main(int argc, char *argv[])
{
const int s = 100, n = 5000;
int i;
void *p = malloc(s);
for (i = 2 ; i <= n ; i++)
p = realloc(p,i * s);
for (i = n - 1 ; i > 0 ; i--)
{
void *newp = realloc(p,i * s);
if (newp != p)
printf("realloc(p,%d * %d = %d) changes pointer from %p to %p\n",i,s,i * s,p,newp);
p = newp;
}
free(p);
return 0;
}
这将触发第二个 for 循环中的 malloc_printf() 断点(当重新分配缩小内存时)并打印:
malloc: *** can't protect(0x3) region for postlude guard page at 0x48ed000
看起来(在 malloc_printf() 上设置断点)这恰好发生在 realloc() 第一次更改返回的指针时,上述程序的总输出为:
realloc(p,1249 * 100 = 124900) changes pointer from 0x48b0000 to 0x5000000
realloc(p,2 * 100 = 200) changes pointer from 0x5000000 to 0x240cc60
使用块大小 s 和迭代次数 n 的组合玩一点,它至少会发生 10/50000、100/5000、200/5000,...,似乎当分配的内存 i * s 缩小到大约 124000 字节。 1/200000 等其他组合不会触发 malloc_printf()。
鉴于此代码 sn-p 的简单性,我们认为这是 Apple 的 malloc 调试实现中的一个错误......或者该消息应该是一些信息性(内部)消息,而不是试图发出真实内存的信号问题。
Apple 的 malloc 实现的源代码(一个版本)可以在这里找到http://www.opensource.apple.com/source/Libc/Libc-391.4.2/gen/scalable_malloc.c?txt。我们正在考虑向 Apple 开发者中心筹集资金...
所以简而言之,答案很可能不是代码中的内存踩踏错误,而是 de malloc 调试代码本身的问题,在这种情况下,您只需忽略该消息。