4 Replies - 410 Views - Last Post: 12 May 2013 - 01:52 PM Rate Topic: -----

#1 noctolater  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 72
  • Joined: 29-April 09

Memory Manager Causes STATUS_ACCESS_VIOLATION

Posted 12 May 2013 - 11:40 AM

I'm rolling my own memory manager for fun and for speed, and have run into a problem that I cannot for the life of me solve. I am creating a bitmapped memory pool, and it seems to allocate just fine. I have even accessed the value in each byte allocated as part of the constructor to test that it allocated correctly. However, when I attempt to use addresses above a specific point in my main function, I get a segfault of STATUS_ACCESS_VIOLATION. I have stripped it down to a very short bit of code, but I still cannot figure out what my issue is.

The index it fails at changes based on the machine and how stripped down I make it (currently fails at index 1021 for me), though changing 'num_elem' doesn't seem to have an effect, making this even more difficult to track down.

I am using cygwin with everything installed and up to date, but when I run the code on a redhat 6.1 linux server I get the same segfault. Both systems are 32 bit. It is being compiled with 'g++ -Wall pool.cpp'

Can anyone help me to track down what my bug is? Any advice at all about where I should be looking would be helpful.

#include <stdlib.h> // malloc, calloc
#include <stdio.h> // printf
#define ELEMS_PER_ENTRY (8 * sizeof(*bitmap))
#define TEST_SIZE 2048

class Pool {
    void *base; /// start of the malloc'ed memory for the pool
    int *bitmap; /// a bitmap
    int elem_size; /// the byte size of each element
    int num_elem; /// the total number of elements in this pool

    // determine the number of bits i's high bit is shifted over
    inline int offset(unsigned int i) {
      int ans = 0;
      while (i >>= 1)
        ans++;
      return ans;
    }

  public:
    // constructor, allocate bitmap and memory pool
    Pool(int _elem_size = 0, int _num_elem = 0)
      : elem_size(_elem_size), num_elem(_num_elem) {
      // initialize the bitmap to all 0's, for unset
      bitmap = (int*) calloc((num_elem / ELEMS_PER_ENTRY), sizeof(*bitmap));
      // initial memory allocation
      base = malloc(num_elem * elem_size);
    }

    // allocate an element
    void* allocate() {
      int shift, i = 0, size = (num_elem / ELEMS_PER_ENTRY);
      void *ans = NULL;

      // find first elem in bitmap not completely used
      while (i < size && bitmap[i] == -1)
        i++;

      // if the bitmap has an unset bit
      if (i < size) {
        shift = offset(~bitmap[i] & (bitmap[i] + 1)); // find first unset bit
        bitmap[i] |= (1 << shift); // set the entry as used
        ans = (void*) (((unsigned int) &base) + 
            (((i * ELEMS_PER_ENTRY) + shift) * elem_size)); // calculate address
      }
      return ans;
    }
};

int main() {
  Pool *p = new Pool(256, TEST_SIZE); // create a new pool

  int *ints[TEST_SIZE], i;
  for (i = 0; i < TEST_SIZE; i++) // allocate all the pointers
    ints[i] = (int*) p->allocate();

  for (i = 0; i < TEST_SIZE; i++) { // use the pointers
    printf("%d, %d\n", i, (int) ints[i]);
    *(ints[i]) = i;
  }
  return 0;
}


This post has been edited by noctolater: 12 May 2013 - 11:40 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Memory Manager Causes STATUS_ACCESS_VIOLATION

#2 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3569
  • View blog
  • Posts: 11,089
  • Joined: 05-May 12

Re: Memory Manager Causes STATUS_ACCESS_VIOLATION

Posted 12 May 2013 - 12:50 PM

Why are you getting the address of base on line 43?
Was This Post Helpful? 0
  • +
  • -

#3 noctolater  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 72
  • Joined: 29-April 09

Re: Memory Manager Causes STATUS_ACCESS_VIOLATION

Posted 12 May 2013 - 01:06 PM

View PostSkydiver, on 12 May 2013 - 12:50 PM, said:

Why are you getting the address of base on line 43?


ans = (void*) (((unsigned int) &base) + 
    (((i * ELEMS_PER_ENTRY) + shift) * elem_size)); // calculate address



In order to calculate the address to give to the program calling allocate(), I need to do pointer math from the start of the allocated memory plus an offset amount of bytes. The offset is basically the index of the block to allocate (i * ELEMS_PER_ENTRY + shift) times the size of each block (elem_size).

I have checked the returned addresses for each element, and they all fall within the range of addresses that I can use from the malloc call in the constructor.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3569
  • View blog
  • Posts: 11,089
  • Joined: 05-May 12

Re: Memory Manager Causes STATUS_ACCESS_VIOLATION

Posted 12 May 2013 - 01:18 PM

View Postnoctolater, on 12 May 2013 - 04:06 PM, said:

I need to do pointer math from the start of the allocated memory plus an offset amount of bytes.


base already contains that address of the start of the allocated memory. By doing &base, you are adding the offset to the address of base. Your goal was to add to the offset to the address contained in base.
Was This Post Helpful? 1
  • +
  • -

#5 noctolater  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 72
  • Joined: 29-April 09

Re: Memory Manager Causes STATUS_ACCESS_VIOLATION

Posted 12 May 2013 - 01:52 PM

Thanks, that fixed it. I swear I have been staring at this for 2 days because I always do that sort of thing with pointers...
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1