-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() を使用するたびに、3 番目のパラメーターの値が 1 から 0 に変わります。行をコメントアウトすると、値は同じになります。この背後にある理由は何でしょうか?

4

2 に答える 2

2

未定義の動作が見られます。sizeof(list)アーキテクチャに応じて、おそらく 4 または 8 バイトであるためmemset、0 を使用すると 4 番目のバイトを超えません。から取得され、まだ初期化されていない3 番目の 32 ビットワードから読み取っています。さらに、12 バイトを割り当てている (に変換されます。小数点以下のバイトを割り当てることができないため、 aまたは aをに渡すことは意味がありません) ため、98 番目のビットにアクセスすると、割り当てられた領域を超えてしまいます。mallocmemsetsize/8.0intfloatdoublemalloc

これらの未定義の動作を修正する必要があります: を使用して十分なメモリを割り当てます。

// 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 に答える