1
votes

I need to allocate all the memory my application will use up front. And then whenever needed overwrite that memory with data I need to do computations on. The memory has to be allocated first before any computations because I'm trying to run a multi-threaded CUDA algorithm in parallel as explained in my question here (Multi-Threaded CPU CUDA application not asynchronous when calling CudaFree).

I thought I could allocate all the memory needed as a byte pointer and then store that pointer as a void pointer:

void * allocateMemory()
{
    byte *mem;
    int nbytes = 13107200;
    mem = (byte *) malloc(nbytes);
    return mem;
}

Later in my program I want to use the memory that's already allocated to store data. I don't know ahead of time what type the data will be but I know it's size won't go over the allocated limit.

void doSomething(void * mem)
{
    int *a = (int*) mem;
    for (int i = 0; i < 100; i++)
    {
        a[i] = i;
    }

    //do stuff

}

There are many other functions like doSomething(void * mem) above but that use type double or type float or maybe even type byte. I need to be able to overwrite the orignally allocated memory with whatever data type I need. The above code does not work because it says I can't deference a void pointer. It also says I attempted to read or write protected memory.

What is the proper way to do this? What is the best way to accomplish my goal of having all my memory allocated at the beginning and then used however necessary throughout? Thanks!

1
You're trying to implement a fixed size heap.. not an easy problem to solve with fragmentation etc. Best bet is to use a pool, perhaps using boost which already has this.paulm
Just saw your other question and I think you've misunderstood the answer. What he is saying is do malloc, loop, free, not begin loop, malloc, free, end loop.paulm
I have done something similar to this in the past where objects are more or less permanently allocated in a contiguous storage area. Fairly easy if you have no need to deallocate/reuse. If you want to be able to deallocate/reuse then you're implementing your own heap (and for that I recommend a Cartesian tree).Hot Licks
(At the very least, though, you need to maintain a "next" pointer that gives the next byte to allocate, and probably also a "max" pointer/length that tells you when you've blown your allocation.)Hot Licks
What you show above is perhaps not the cleanest, cleverest way to do it, but it should work. I suspect that your problem is somewhere else.Hot Licks

1 Answers

1
votes

It sounds like you have two problems.

  1. Cannot dereference a void pointer. Somewhere in your code you have used the result from allocateMemory() without a cast. The code you give is OK, but whatever line the compiler is flagging as wrong is not OK. For example, maybe you have:

    void *foo = allocateMemory();
    foo[42];  // compiler doesn't have a real type here - error
    ((int*)foo)[42];  // compiler happy
    
  2. Attempted to access protected memory. Somewhere in your code you have an invalid pointer. The most likely cause is that allocateMemory() is returning NULL (which you are not checking for).

Your general approach seems OK to me; the issues you describe are related to details in your code, not the overall idea.