1

我在 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 编译。

4

1 回答 1

0

问题是未能包括为 realloc()、malloc() 等获取正确的原型。添加解决了该问题。感谢 Wiz 和 tristopia 指出这一点。

我仍然不清楚为什么这个问题只出现在 OS/X 上(这让我怀疑有更复杂的事情)。

于 2013-08-07T09:52:53.427 回答