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.如果我注释掉该行,那么值是相同的。这背后可能是什么原因?
答案 0 :(得分:2)
您会看到未定义的行为:sizeof(list)
可能是4或8个字节,具体取决于体系结构,因此带有零的memset
不会超过第四个字节。您正在阅读来自malloc
的第三个32位字,但尚未由memset
初始化。此外,您正在分配12个字节(size/8.0
转换为int
;将float
或double
传递给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()
分配内存。