为什么fopen()会更改数组中元素的值?

时间:2013-01-07 20:13:55

标签: c

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.如果我注释掉该行,那么值是相同的。这背后可能是什么原因?

2 个答案:

答案 0 :(得分:2)

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

您应该修复这些未定义的行为:使用

分配足够的内存
// 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);

答案 1 :(得分: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()分配内存。

祝你好运。