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. ビルド 5658 に基づく) (LLVM ビルド 2336.9.00)
daphne:java shane$ java -version Java バージョン "1.6.0_51" Java(TM) SE ランタイム環境 (ビルド 1.6.0_51-b11-457-11M4509) Java HotSpot(TM) 64 ビット サーバー VM (ビルド 20.51-b01- 457、混合モード)
C コードは、autoconf/automake によってコンパイルされています。