views:

85

answers:

3

Hi

I am about to create a bitmap that holds control of 512 bits, all 512 bits should be 0 to indicate that the bit is free when the program starts. Function occupyDataBlocks(int number) should find free bits put the position of the bit in the array int data_blocks[] and set the occupied bit to 1.

Under is some code that does some of the work: Except that char bit[512/8] is declared inside the function so the array will be declared when I call occupyDataBlocks something that makes the same output and a big fail in my prog, the programs return Not enough memory when I try to declare char bit as an global variable.

I need help to get the code to achieve this, and to set the bit to occupied. Please give me a coding hand, I have a understanding of the solutions but cant express it in C.

        #include <stdio.h>
        #include <string.h>

        void occupyDataBlocks(int number)
        {

            int ab = number;

            char bit[512/8];

            int bitNum = 0;

            int count;

            int data_blocks[ab];

            int b = 0;

            for(bitNum = 0; bitNum < (sizeof(bit)/sizeof(char)); bitNum++) {
                char x = bit[bitNum];

                for(count = 0; x != 0; x >>= 1 ) {
                    if(!(x & 0)) {
                        data_blocks[b++] = count;
                    }

                    if(count == number) {
                        break;
                    }
                    count++;
                }
                if(count == number) {
                    break;
                }
            }

            if(count == number) {
                int a;

                for(a = 0; a < 5; a++) {
                    printf("%d\n", data_blocks[a]);
                }

            } else {
                printf("Not enough data blocks\n");
            }
        }

        int main(void)
        {
            occupyDataBlocks(3);
            occupyDataBlocks(3);


            return 1;
        }

#include <stdio.h>
#include <string.h>

int occupyDataBlocks(char bit, int number)
{

    int ab = number;

    int bitNum = 0;

    int count;

    int data_blocks[ab];

    int b = 0;

    for(bitNum = 0; bitNum < (sizeof(bit)/sizeof(char)); bitNum++) {
        char x = bit[bitNum];

        for(count = 0; x != 0; x >>= 1 ) {
            if(!(x & 0)) {
                data_blocks[b++] = count;
            }

            if(count == number) {
                break;
            }
            count++;
        }
        if(count == number) {
            break;
        }
    }

    if(count == number) {
        int a;

        for(a = 0; a < 5; a++) {
            printf("%d\n", data_blocks[a]);
        }

    } else {
        printf("Not enough data blocks\n");

        return 0;
    }

    return 1;
}

int main(void)
{
    unsigned char bit[512/8];

    /*
     * I need 3 data blocks that is ready for me to use. Put the position to the free data block in array data_blocks[],
     * where data_blocks[0] can be 100 (the first free data block), data_block[1] = 400 (second free datablock) etc.
     *
     */

    int data_blocks[3];
        memcpy(data_blocks, occupyDataBlocks(bit, 3), sizeof(data_blocks));/* A try to copy the result of occypyDataBlocks to data_blocks*/

    return 1;
}
A: 

Some points that may help:

  • It is not valid C (except in C99) to declare "variable-sized arrays" such as int data_blocks[ab];. You may need to use malloc().
  • (x & 0) will always equal 0.
  • if (count == number) doesn't make any sense.
  • You need to work out what happens if there aren't enough free bits.
Oli Charlesworth
variable sized arrays are legal in C99.
tristopia
@tristopia: Indeed. But not all C is C99!
Oli Charlesworth
C99 is the current standard.
Jens Gustedt
@Jens: Indeed, but that doesn't invalidate "not all C is C99". I always write my C for the lowest common denominator, to ensure maximum portability. YMMV.
Oli Charlesworth
Yes, but to say it's not valid C is also not true. Now that you have edited your first point it's ok.
tristopia
A: 

As you mentioned, the array bit need to maintain state outside of the function occupyDataBlocks(). For this program, you can define them in main() and pass it to the function as

int main() {

    unsigned char bit[512/8];      // Note: unsigned

    occupyDataBlocks( bit, 3 );
    occupyDataBlocks( bit, 3 );
}

I am still unclear why the int data_blocks[] array. If you update your question with more precise requirements and two examples, then I may be able to offer better suggestions.

ArunSaha
Thanks. Look at the code now (at the bottom). ;D
A: 

I'm not sure, what you want to do, reading your code. Either it is too confusing or too bugy.

1.) If you want to "break" out of more than one loop, you might want to write a helper function for the loops, and "return" instead.

2.) I'm not sure wether you know this: b++ means: Return the value of b and then increment the variable afterwards.

b++ equals:
{int x=b; b=b+1; return x;}

++b equals:
{b=b+1; return b;}

3.) The operators & and | and ^ are bitwise, && and || and ! are boolean operators, which implicitely cast the 0/NULL to false/0 and everything else to true/1. So, (x & 0) always equals to 0, and !(x & 0) equals to 1.

4.) I'm not that sure about this, my C-knowledge is not complete: What is the value of this:

((signed char)0xff) >> 1  == 0xff
or
((signed char)0xff) >> 1  == 0x7f

chars are officially neither signed chars nor unsigned chars; they are different types, which might be similar to signed or unsigned chars, depending on the compiler.

5.) This code equals:

for(a,aa;b;c,cc)d,dd;

{a;aa; while(b){d;dd;c;cc;} }

Using a for instead of while might make things clear, but those three parameters of the for should be explicitely used to make things clear. For the compiler this is not that relevant, but for the reader.

6.) sizeof(char) is always 1. What you might want to write is sth like this: (sizeof(myarray)/sizeof(myarray[0]))

comonad