-1

So, been building this class:

public class BitArray {
public:
    unsigned char* Data;
    UInt64 BitLen;
    UInt64 ByteLen;

private:
    void SetLen(UInt64 BitLen) {
        this->BitLen = BitLen;
        ByteLen = (BitLen + 7) / 8;
        Data = new unsigned char(ByteLen + 1);
        Data[ByteLen] = 0;
    }

public:
    BitArray(UInt64 BitLen) {
        SetLen(BitLen);
    }

    BitArray(unsigned char* Data, UInt64 BitLen) {
        SetLen(BitLen);
        memcpy(this->Data, Data, ByteLen);
    }

    unsigned char GetByte(UInt64 BitStart) {
        UInt64 ByteStart = BitStart / 8;
        unsigned char BitsLow = (BitStart - ByteStart * 8);
        unsigned char BitsHigh = 8 - BitsLow;

        unsigned char high = (Data[ByteStart] & ((1 << BitsHigh) - 1)) << BitsLow;  
        unsigned char low = (Data[ByteStart + 1] >> BitsHigh) & ((1 << BitsLow) - 1);

        return high | low;
    }

    BitArray* SubArray(UInt64 BitStart, UInt64 BitLen) {
        BitArray* ret = new BitArray(BitLen);
        UInt64 rc = 0;

        for (UInt64 i = BitStart; i < BitLen; i += 8) {
            ret->Data[rc] = GetByte(i);
            rc++;
        }

        Data[rc - 1] ^= (1 << (BitLen - ret->ByteLen * 8)) - 1;

        return ret;
    }

};

just finished writing the SubArray function and went on to test but I get "Access violation: attempted to read protected memory" on the line where GetByte(i) gets called. I tested a bit and it doesn't seem to have anything to do with the data array or i, placing "int derp = GetByte(0)" on the first line of the function produces the same error.

calling GetByte from outside the class works fine, I don't understand whats going on.

the test function looks like this:

        unsigned char test[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
        BitArray* juku = new BitArray(test, 64);

        auto banana = juku->GetByte(7); //this works fine
        auto pie = juku->SubArray(7, 8);
user81993
  • 6,167
  • 6
  • 32
  • 64
  • So did you debug it? How are you calling `SubArray`? What are the values of all of your variables? You should be able to work this out on paper. – Lightness Races in Orbit Oct 29 '14 at 11:50
  • debug it? when i hit run in VS in debug mode all i get is the access violation error. – user81993 Oct 29 '14 at 11:52
  • 1
    `public class`? Is that an VC++ extension? also, how does your main() look like? Please provide an [SSCCE](http://sscce.org) so that we can reproduce the issue. – Andreas Fester Oct 29 '14 at 11:54
  • 1
    @user81993: Yes, debug it. Y'know, with your _debugger_. So you can step through the code, set breakpoints, and analyse the values of all your variables and find out specifics about the access violation. – Lightness Races in Orbit Oct 29 '14 at 11:56

1 Answers1

2

You might want to consider creating an array of characters, changing:

Data = new unsigned char(ByteLen + 1);

into:

Data = new unsigned char[ByteLen + 1];

In the former, the value inside the parentheses is not the desired length, it's the value that *Data gets initialised to. If you use 65 (in an ASCII system), the first character becomes A.

Having said that, C++ already has a pretty efficient std::bitset for exactly the situation you seem to be in. If your intent is to learn how to make classes, by all means write your own. However, if you want to just make your life simple, you may want to consider using the facilities already provided rather than rolling your own.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953