//查找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位系统导致的差异?
可能需要更多实验,或者查找一些书籍来弄明白这个问题。
也希望知道答案的朋友能留言告诉我。谢谢!