0

I am trying to take this byte stream of information (1's and 0's) and im trying to store this in a uint8_t array (each index would be a byte long, 8 bits). I am having a hard time grasping how to store 8 bits into 1 index location for the given bitmapSize (For this example its 4).

So we would have a uint8_t array of size 4 with output looking like the following:

Array output --> 11111100 00011110 00001111 01

Any help would be appreciated!! Thank you!

  int allocatedMem[26] = { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1 };
  int bitmapSize = 0;
    
  for (int i = 0; i < sizeof(allocatedMem) / sizeof(allocatedMem[0]); i +=8)
  {
    bitmapSize++;
  }

  cout << "Size of bitmap: " << bitmapSize << endl;
  • 26 is not an even multiple of 8, what should happen with the missing bits? Look up bitwise operators – NathanOliver Mar 13 '22 at 22:04
  • It would just be 0, basically just padding and will do – tristan bottone Mar 13 '22 at 22:06
  • Is this an exercise or can you just use std::vector? – Goswin von Brederlow Mar 13 '22 at 22:46
  • Its part of a project, we are making a memory management system and one of the requirements is to return a bitstream of allocated memory (1) and free memory (0). Its basically just returning the allocatedMem array as a series of bytes, which get converted to decimal – tristan bottone Mar 13 '22 at 22:54
  • First thing you have to compute the size of the bitmap you need. So the size of allocatedMem divided by the size of the storage type you use for the bitmap (byte == 1) times the bits of that type (CHAR_BITS for char, 8 for uint8_t, sizeof(size_t) * CHAR_BITS for best speed). And then you loop over allocatedMem and shift the bits into a temp. Every time it is full you store it. And after the loop you store the partial bits if allocatedMem was unaligned. – Goswin von Brederlow Mar 14 '22 at 16:09

1 Answers1

0

Some code to allocate and initialize a Bitmap with your data in a freestanding environment + malloc/free/assert:

#include <cstddef>  // size_t
#include <cstdint>  // uint8_t
#include <climits>  // CHAR_BIT

#include <cassert>  // assert
#include <cstring>  // malloc / free
#include <iostream> // for output only
#include <bitset>   // for output only

// variable sized arrays in structs are only defined in C
extern "C" {
    struct Bitmap {
        using word = uint8_t;
        static constexpr size_t wordsize = sizeof(word) * CHAR_BIT;
        size_t size;
        word map[];
    };
}
using Bitmap = struct Bitmap;

// Cpp Core Guidelines violation:
// don't return ownership as pointer
// don't take array+size separately
Bitmap * alloc_init_bitmap(int allocated[], size_t n) {    
    // calculate bitmap size without risk of overflow
    const size_t bitmap_size = [](size_t n) {
        size_t t = n / Bitmap::wordsize;
        if (t * Bitmap::wordsize < n) ++t;
        return t;
    }(n);

    // allocate Bitmap
    const size_t total_size = offsetof(Bitmap, map) + bitmap_size;
    Bitmap *bitmap = (Bitmap*)malloc(total_size);
    assert(bitmap != nullptr);
    bitmap->size = n;

    // initialize bits
    Bitmap::word t = 0;
    Bitmap::word *pos = bitmap->map;
    Bitmap::word bit = 1;
    while (n-- > 0) {
        // add bit by bit from allocated to t
        t = t | bit * (*allocated++ != 0);
        bit <<= 1;
        if (bit == 0) {
            // all bits in t have been set, store word
            *pos++ = t;
            t = 0;
            bit = 1;
        }
    }
    // store partial word if allocatedMem isn't multiple of words
    if (bitmap->size % Bitmap::wordsize != 0) *pos = t;

    return bitmap;
}

int main() {
    int allocatedMem[26] = { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1 };
    Bitmap *bitmap = alloc_init_bitmap(allocatedMem, sizeof(allocatedMem) / sizeof(allocatedMem[0]));
    std::cout << "Bitmap of size " << bitmap->size << ":\n";
    for (size_t i = 0; i < bitmap->size / Bitmap::wordsize; ++i) {
        std::cout << " " << std::bitset<8>(bitmap->map[i]);
    }
    std::cout << std::endl;
    free(bitmap);
}

Demo

The use of std::bitset is purely to output the map. The malloc/free you have to replace with your own way of getting some memory for the bitmap. If the bitmap is for managing memory this is a bit of a vicious circle.

The output looks different then allocatedMem because each word is output with bit 0 on the right and bit 7 on the left.

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42