Malloc with placement new

Okay, I'm a little confused. I'm just playing around with malloc and placement new, and I'm struggling a little bit with how a class is allocated.

foo* mem_pool = (foo*) malloc(sizeof(foo)*3);

After defining a memory pool with room for 3 foo objects, I attempted to create a class in the pool with placement new. If it is the first one written to the pool (any arbitrary location, though I am using the beginning here), I can dereference it correctly. Cool.

1
2
3
foo* sPtr1 = new (mem_pool) foo(3.1, 4.1); //create foo object at beginning of pool
mem_pool->x; //returns 3.1
mem_pool->y; //return 4.1 


After that, I attempt to write a second class at mem_pool+sizeof(foo). The dereference returns junk data...
1
2
3
foo* sPtr2 = new (mem_pool+sizeof(foo)) foo(7.5, 8.5);
(mem_pool+sizeof(foo))->x; //returns 2.63159e+265
(mem_pool+sizeof(foo))->y; //return 4.06784e+265 


I'm thinking it might be because of a memory overlap because it works just fine if it's the only one allocated. However, when I do
(mem_pool+sizeof(foo)+4)->x;
it crashes the program.


It also works correctly when using ints. I guess I don't understand how doubles are aligned in a class. Does anyone want to enlighten me about what I am doing wrong?



Here is the entire code...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

class foo {
public:
    foo(double a, double b) : x(a), y(b) { };

    double x;
    double y;
};

int main() {
    size_t size = sizeof(foo)*3;

    foo* mem_pool = (foo*) malloc(size); //allocate enough space for 3 'foo' objects
    memset(mem_pool,0,size-1); //set all to 0

    foo* sPtr1 = new (mem_pool) foo(3.1, 4.1); //create foo object at beginning of pool
    foo* sPtr2 = new (mem_pool+sizeof(foo)) foo(7.5, 8.5);

    for(size_t ii = 0; ii < size; ii++) {
        if(ii<10) cout << " "; //Spacing

        cout << ii << " : " << mem_pool+ii;

        //dereference
        if(mem_pool+ii == sPtr1) { cout << " = " << (mem_pool+ii)->x << " : " << (mem_pool+ii)->y; }
        if(mem_pool+ii == sPtr2) { cout << " = " << (mem_pool+ii)->x << " : " << (mem_pool+ii)->y; }
        cout << endl;
    }

    delete mem_pool;
}
Last edited on
if you're dead set on using malloc, then use free to free up whatever you malloc'd.

similarly, if you're dead set on using delete, then use new to allocate the memory

You should DEFINITELY be using new and delete in my opinion. New and delete are used for allocation and deletion of memory of classes, malloc is a lot more flexible (and therefore more dangerous).

instead of
 
foo* mem_pool = (foo*) malloc(size); //allocate enough space for 3 'foo' objects 


use
 
foo* mem_pool = new foo[size]; //allocate enough space for 3 'foo' objects 


hope that helps
Your pointer arithmetic is wrong. To allocate the second object you use mem_pool + 1, not mem_pool + sizeof(foo). If your mem_pool pointer were of type char or unsigned char, then yes, it would be as you have it.
Interesting you're are trying to manage classes using memory pools. So in theory you could deconstruct a group of classes just using one free command. I don't think using new or delete for this purpose would work since they are probably used for single class allocation and not multiple.
Last edited on
If you use placement new, you need "placement delete"

If you want to get the info from someone trustworthy, see
http://www2.research.att.com/~bs/bs_faq2.html#placement-delete

Andy
Thank you very much webJose, that is exactly what I was getting wrong. I went ahead and read up on pointer arithmetic so I could get a better understanding of how they worked. ;)

@ceruleus Actually, I overlooked that I was using delete instead of free at the very end. That's my bad. :P I wanted to experiment with void* pools for flexibility, and using new requires that I use objects.

@cppabuser/andywestken I wasn't planning on using delete to manage the objects inside the pools. I wanted to try out overloading new/delete so it would simply mark 'deleted' objects as available. Then at the end of the program, all I would do is free the pools for garbage collection.

Anyways, I had another question. I decided to go the route for using char* for pointer arithmetic. However, what would I do if the compiler's sizeof(char) is not equal to 1? Is there a way I can explicity define that, or a 1 byte pointer?

[edit] Never mind, I just found my answer. http://www.parashift.com/c++-faq-lite/intrinsic-types.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstdlib>
using namespace std;

class foo {
public:
    foo(double a, double b) : x(a), y(b) {}
    friend ostream& operator<<(ostream&os, const foo& ob);

private:
    double x, y;
};

ostream& operator<<(ostream& os, const foo& ob) {
    os << "(" << ob.x << ", " << ob.y << ")" << endl;
    return os;
}

int main() {
    size_t poolsize =  3;

    void* pool = malloc(sizeof(foo)*poolsize);
    cout << "Pool created at " << pool << endl;

    //declare void pointers within pool
    void* _vptr1 = (char*) pool + sizeof(foo)*0;
    void* _vptr2 = (char*) pool + sizeof(foo)*1;
    void* _vptr3 = (char*) pool + sizeof(foo)*2;

    //create object at each void pointer
    foo*   vptr1 = new (_vptr1) foo(1.5, 2.5);
    foo*   vptr2 = new (_vptr2) foo(3.5, 4.5);
    foo*   vptr3 = new (_vptr3) foo(5.5, 5.5);

    cout << "Size of foo : " << sizeof(foo) << endl;
    cout << vptr1  << " = " << *vptr1;
    cout << vptr2  << " = " << *vptr2;
    cout << vptr3  << " = " << *vptr3;

    free(pool);
}

Last edited on
Topic archived. No new replies allowed.