我目前正试图弄清楚Android Native堆的工作方式:我正在通过new在堆上分配一些内存,然后打印指针的地址以查看内存的分配位置。但是,内存分配的地址似乎没有遵循简单的模式,例如,当我尝试执行此操作时:
//native-lib.cpp (in in Android App)
int *pInt1 = new int();
int *pInt2 = new int ();
int *pInt3 = new int ();
int *pInt4 = new int ();
int *pInt5 = new int ();
int *pInt6 = new int ();
int *pInt7 = new int ();
int *pInt8 = new int [100000];
int *pInt9 = new int [99999999];
int *pInt10 = new int ();
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 1:", "%p\n", pInt1);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 2:", "%p\n", pInt2);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 3:", "%p\n", pInt3);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 4:", "%p\n", pInt4);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 5:", "%p\n", pInt5);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 6:", "%p\n", pInt6);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 7:", "%p\n", pInt7);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 8:", "%p\n", pInt8);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 9:", "%p\n", pInt9);
__android_log_print(ANDROID_LOG_ERROR, "ADDRESS INT 10:", "%p\n", pInt10);
我从日志中得到的结果是:
E/ADDRESS INT 1:: 0xacb78ac0
E/ADDRESS INT 2:: 0xacb78b10
E/ADDRESS INT 3:: 0xacb78ab8
E/ADDRESS INT 4:: 0xacb78a00
E/ADDRESS INT 5:: 0xacb78a10
E/ADDRESS INT 6:: 0xacb78a18
E/ADDRESS INT 7:: 0xacb78a88
E/ADDRESS INT 8:: 0xb3900000
E/ADDRESS INT 9:: 0x89c00000
E/ADDRESS INT 10:: 0xacb78a90
这对我没有任何意义,因为pInt2的地址大于pInt1的地址,但pInt3小于pInt1和pInt2,依此类推。当我为大型整数数组(pInt8和pInt9)分配内存时,似乎在堆上分配内存的位置也会发生变化,并且对我来说似乎是任意的。
有人可以解释吗?还是Android NDK堆到底如何工作?我希望堆只会朝一个方向增长,而且我也希望堆是完全连续的,这显然不是来自我的实验,所以我真的不知道发生了什么。
答案 0 :(得分:0)
new返回的地址是一个虚拟地址,系统要花更多的精力来随机化这些地址,从而使某些黑客攻击更加困难。