-1
int getbit(int * list, int n)
{
    return (list[n / 32] >> (n % 32)) & 1;
}
void setbit(int * list, int n)
{
    list[n / 32] |= 1 << (n % 32);
}
int main()
{
    FILE * out;
    int size = 99; //2000000000;
    int root = sqrt(size);
    int * list = malloc(size / 8.0); //(2*10^9)/8
    memset(list, 0, sizeof list);
    int i, j;
    for (i = 2; i <= root; i++)
        for (j = 2 * i; j < size; j += i)
            setbit(list, j);
    printf("i=%d j=%d 98=%d\n", i, j, getbit(list, 98));
    out = fopen("output.txt", "w");
    printf("i=%d j=%d 98=%d\n", i, j, getbit(list, 98));
    /*for (i=2; i<size; i++)
    if (!getbit(list, i))
        fprintf(out, "%d\n", i);
     fclose(out);*/
    return 0;
}

每当我在 printf 之间使用 fopen() 时,第三个参数的值就会从 1 变为 0。如果我注释掉该行,那么该值是相同的。这背后的原因可能是什么?

4

2 回答 2

2

您会看到未定义的行为:sizeof(list)可能是 4 或 8 个字节,具体取决于架构,因此memset零不会超过第四个字节。您正在读取第三个 32 位word,它来自malloc并且尚未被初始化memset。此外,您分配了 12 个字节(size/8.0转换为;将 a或 a传递给int永远没有意义,因为您不能分配小数字节),因此访问第 98 位会超出分配的区域。floatdoublemalloc

您应该修复这些未定义的行为:通过使用分配足够的内存

// count needs to be a multiple of sizeof(int)
// The math gets pretty ugly here, but it should work:
int count = sizeof(int)*(size+(8*sizeof(int))-1)/(8*sizeof(int));
int * list = malloc(count);

然后使用适当的大小将数据初始化为零:

memset(list, 0, count);
于 2013-01-07T20:21:55.237 回答
0

您正在写入您不拥有的内存,具有未定义的行为。

首先,您在这里只分配 12 个字节:

int* list = malloc(size / 8.0);

你应该这样做(只是给你的想法,我不知道你真正想要分配多少字节..):

int* list = malloc((size / 8.0) * sizeof(*list));

其次,你在这里只设置 4 个字节(如果你在 32 位系统上):

memset(list, 0, sizeof list);

你应该做这个:

memset(list, 0, (size / 8.0) * sizeof(*list));

最后,您调用fopen()更改内容的唯一原因是fopen()分配内存。

祝你好运。

于 2013-01-07T20:25:18.913 回答