我在 JNI 库中有以下代码。这可以在 ARM 和 x86 架构上的 Linux(32 位和 64 位)下按预期编译和工作。为简洁起见,我删除了一些错误检查和其他代码。
// Globals:
//
// uint8_t *g_assets (initialised to NULL)
// uint32_t g_nextIndex (initialised to 0)
//
// Parameters:
//
// uint32_t size (number of extra bytes to allocate)
// Try and reallocate the array to fit the new data
uint8_t *pNew = (uint8_t *)realloc(g_assets, g_nextIndex + size);
if(pNew==NULL)
return -1;
g_assets = pNew;
在 OS/X 上,对 realloc() 的调用成功(不返回 NULL),但任何访问 g_assets 内容的尝试都会导致如下消息:
Invalid memory access of location 0x72911f20 rip=0x7fff90b35fd7
通过添加一些 printf 语句来显示指针的值,它们似乎要么作为 32 位值返回,要么作为设置了最高 32 位的 64 位值返回(例如:0xffffffffcb41cc80)。
我将代码更改为以下内容:
void *pBuffer;
if(g_assets==NULL)
pBuffer = malloc(size);
else
pBuffer = realloc(g_assets, g_nextIndex + size);
if(pBuffer==NULL)
return -1;
g_assets = pBuffer;
在第一次调用 malloc() 调用返回一个完整的 64 位指针(并且写入内存不会触发无效的内存访问)但随后对 realloc() 的调用以尝试扩展缓冲区的大小表现出与前。我在测试期间产生的一些示例调试输出如下:
// Add first item, 32 bytes long
addAsset: g_assets = 0x0, g_nextIndex = 0, size = 32
addAsset: pBuffer = 0x7f8372912260, g_assets = 0x7f8372912260, g_nextIndex = 0, size = 32
// Add second item, 450 bytes long
addAsset: g_assets = 0x7f8372912260, g_nextIndex = 32, size = 450
addAsset: pBuffer = 0x72911f00, g_assets = 0x72911f00, g_nextIndex = 32, size = 450
如您所见, realloc() 似乎出于某种原因将指针截断为 32 位。任何帮助将不胜感激,因为这变得非常令人沮丧。
我的环境:
daphne:java shane$ gcc --version i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (基于 Apple Inc. build 5658) (LLVM build 2336.9.00)
daphne:java shane$ java -version java version "1.6.0_51" Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457-11M4509) Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01- 457,混合模式)
C 代码正在通过 autoconf/automake 编译。