//查找100以內的素數
#include <stdio.h>
#include <unistd.h>
//素數檢測函數
int isPrimer(int a)
{
int i;
for(i = 2; i < a; i++)
{
if(a % i == 0)
{
return 1;
}
}
return 0;
}
int main(void)
{
int i = 2;
int b;
int *r;
int *p;
p = sbrk(0);
r = p;
for (; i < 100; i++)
{
b = isPrimer(i);
if (b == 0)
{
brk(r + 1);
*r = i;
r = sbrk(0);
//printf("i = %d, sbrk(0) = %p\n", i, sbrk(0));
}
}
r = p;
printf("r = %p, sbrk(0) = %p\n", r, sbrk(0));
while(r != sbrk(0))
{
printf("sbrk(0) = %p, r = %p : %d\n", sbrk(0), r, *r);
r++;
sleep(1);
}
return 0;
}
以上函數是一個查找100以內素數的一個簡易函數。
但在Ubuntu 18.04.4 LTS 64位系統中,卻在任意一次執行中出現瞭如下結果:
r = 0x556ca4041000, sbrk(0) = 0x556ca4041064
sbrk(0) = 0x556ca4063000, r = 0x556ca4041000 : 2
sbrk(0) = 0x556ca4063000, r = 0x556ca4041004 : 3
sbrk(0) = 0x556ca4063000, r = 0x556ca4041008 : 5
sbrk(0) = 0x556ca4063000, r = 0x556ca404100c : 7
sbrk(0) = 0x556ca4063000, r = 0x556ca4041010 : 11
sbrk(0) = 0x556ca4063000, r = 0x556ca4041014 : 13
sbrk(0) = 0x556ca4063000, r = 0x556ca4041018 : 17
sbrk(0) = 0x556ca4063000, r = 0x556ca404101c : 19
sbrk(0) = 0x556ca4063000, r = 0x556ca4041020 : 23
sbrk(0) = 0x556ca4063000, r = 0x556ca4041024 : 29
sbrk(0) = 0x556ca4063000, r = 0x556ca4041028 : 31
sbrk(0) = 0x556ca4063000, r = 0x556ca404102c : 37
sbrk(0) = 0x556ca4063000, r = 0x556ca4041030 : 41
sbrk(0) = 0x556ca4063000, r = 0x556ca4041034 : 43
sbrk(0) = 0x556ca4063000, r = 0x556ca4041038 : 47
sbrk(0) = 0x556ca4063000, r = 0x556ca404103c : 53
sbrk(0) = 0x556ca4063000, r = 0x556ca4041040 : 59
sbrk(0) = 0x556ca4063000, r = 0x556ca4041044 : 61
sbrk(0) = 0x556ca4063000, r = 0x556ca4041048 : 67
sbrk(0) = 0x556ca4063000, r = 0x556ca404104c : 71
sbrk(0) = 0x556ca4063000, r = 0x556ca4041050 : 73
sbrk(0) = 0x556ca4063000, r = 0x556ca4041054 : 79
sbrk(0) = 0x556ca4063000, r = 0x556ca4041058 : 83
sbrk(0) = 0x556ca4063000, r = 0x556ca404105c : 89
sbrk(0) = 0x556ca4063000, r = 0x556ca4041060 : 97
sbrk(0) = 0x556ca4063000, r = 0x556ca4041064 : 0
sbrk(0) = 0x556ca4063000, r = 0x556ca4041068 : 0
sbrk(0) = 0x556ca4063000, r = 0x556ca404106c : 0
sbrk(0) = 0x556ca4063000, r = 0x556ca4041070 : 0
......
也即是在最後打印兩次sbrk(0)的返回值結果不一樣。
while循環之前sbrk(0)是正確的0x556ca4041064,
但在執行while循環時,sbrk(0)變成了0x556ca4063000,導致最後想打印100以內的素數時出現了錯誤。多打印了很多沒用的0值。
把sleep(1);去掉將會看見明顯的效果。
但是當我把printf("i = %d, sbrk(0) = %p\n", i, sbrk(0));這一句打開時,程序又得到了正常的運行。
i = 2, sbrk(0) = 0x55bbaa931004
i = 3, sbrk(0) = 0x55bbaa931008
i = 5, sbrk(0) = 0x55bbaa93100c
i = 7, sbrk(0) = 0x55bbaa931010
i = 11, sbrk(0) = 0x55bbaa931014
i = 13, sbrk(0) = 0x55bbaa931018
i = 17, sbrk(0) = 0x55bbaa93101c
i = 19, sbrk(0) = 0x55bbaa931020
i = 23, sbrk(0) = 0x55bbaa931024
i = 29, sbrk(0) = 0x55bbaa931028
i = 31, sbrk(0) = 0x55bbaa93102c
i = 37, sbrk(0) = 0x55bbaa931030
i = 41, sbrk(0) = 0x55bbaa931034
i = 43, sbrk(0) = 0x55bbaa931038
i = 47, sbrk(0) = 0x55bbaa93103c
i = 53, sbrk(0) = 0x55bbaa931040
i = 59, sbrk(0) = 0x55bbaa931044
i = 61, sbrk(0) = 0x55bbaa931048
i = 67, sbrk(0) = 0x55bbaa93104c
i = 71, sbrk(0) = 0x55bbaa931050
i = 73, sbrk(0) = 0x55bbaa931054
i = 79, sbrk(0) = 0x55bbaa931058
i = 83, sbrk(0) = 0x55bbaa93105c
i = 89, sbrk(0) = 0x55bbaa931060
i = 97, sbrk(0) = 0x55bbaa931064
r = 0x55bbaa931000, sbrk(0) = 0x55bbaa931064
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931000 : 2
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931004 : 3
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931008 : 5
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa93100c : 7
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931010 : 11
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931014 : 13
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931018 : 17
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa93101c : 19
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931020 : 23
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931024 : 29
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931028 : 31
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa93102c : 37
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931030 : 41
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931034 : 43
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931038 : 47
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa93103c : 53
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931040 : 59
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931044 : 61
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931048 : 67
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa93104c : 71
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931050 : 73
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931054 : 79
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931058 : 83
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa93105c : 89
sbrk(0) = 0x55bbaa931064, r = 0x55bbaa931060 : 97
而在Ubuntu 14.04.6 LTS 32位或者版本中,得到正確的執行。如下所示:
r = 0x9d52000, sbrk(0) = 0x9d52064
sbrk(0) = 0x9d52064, r = 0x9d52000 : 2
sbrk(0) = 0x9d52064, r = 0x9d52004 : 3
sbrk(0) = 0x9d52064, r = 0x9d52008 : 5
sbrk(0) = 0x9d52064, r = 0x9d5200c : 7
sbrk(0) = 0x9d52064, r = 0x9d52010 : 11
sbrk(0) = 0x9d52064, r = 0x9d52014 : 13
sbrk(0) = 0x9d52064, r = 0x9d52018 : 17
sbrk(0) = 0x9d52064, r = 0x9d5201c : 19
sbrk(0) = 0x9d52064, r = 0x9d52020 : 23
sbrk(0) = 0x9d52064, r = 0x9d52024 : 29
sbrk(0) = 0x9d52064, r = 0x9d52028 : 31
sbrk(0) = 0x9d52064, r = 0x9d5202c : 37
sbrk(0) = 0x9d52064, r = 0x9d52030 : 41
sbrk(0) = 0x9d52064, r = 0x9d52034 : 43
sbrk(0) = 0x9d52064, r = 0x9d52038 : 47
sbrk(0) = 0x9d52064, r = 0x9d5203c : 53
sbrk(0) = 0x9d52064, r = 0x9d52040 : 59
sbrk(0) = 0x9d52064, r = 0x9d52044 : 61
sbrk(0) = 0x9d52064, r = 0x9d52048 : 67
sbrk(0) = 0x9d52064, r = 0x9d5204c : 71
sbrk(0) = 0x9d52064, r = 0x9d52050 : 73
sbrk(0) = 0x9d52064, r = 0x9d52054 : 79
sbrk(0) = 0x9d52064, r = 0x9d52058 : 83
sbrk(0) = 0x9d52064, r = 0x9d5205c : 89
sbrk(0) = 0x9d52064, r = 0x9d52060 : 97
ubuntu18和ubuntu14 gcc 編譯器版本不同。
爲什麼會導致這個問題呢?sbrk(0)返回值在沒有重新分配空間的情況下爲什麼會變化呢?
是gcc編譯器版本的問題嗎?還是不同的內核版本導致了sbrk系統函數的運行機制不同?或者是64位和32位系統導致的差異?
可能需要更多實驗,或者查找一些書籍來弄明白這個問題。
也希望知道答案的朋友能留言告訴我。謝謝!