sbrk系统函数在Ubuntu 18.04.4 LTS 64位系统中的一些疑问

//查找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位系统导致的差异?

可能需要更多实验,或者查找一些书籍来弄明白这个问题。

也希望知道答案的朋友能留言告诉我。谢谢!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值