tags:

views:

90

answers:

4

The closest thread to my question is here. I am trying to compile the following code with gcc:

#include <malloc.h>

class A
{
public:
  A(){};  
  ~A(){};
};//class A

int main()
{
  A* obj = (A*) malloc( sizeof(A) );
  if(obj==0) return 1 ;
  obj->A::A(); /*error: invalid use of 'class A' */
  obj->A::~A();
  free(obj);
  return 0;  
};//

From the command line I compile the code with:

$ g++ -o main main.cpp  
main.cpp: In function 'int main()':  
main.cpp:22: error: invalid use of 'class A'

Can you please point me in the right direction?

+2  A: 

There is no need for malloc business in C++. Simply do:

A* obj = new A();

new allocates the memory and calls the constructor for you.

And, to destroy it, do:

delete a;

delete calls the deconstructor method and frees the memory.

orangeoctopus
malloc is serious business.
Marc Bollinger
+8  A: 

You want a placement-new instead.

void* ptr = malloc(sizeof(A));
A* obj = new(ptr) A;
KennyTM
how does the allocator work in this case, same way as it does its' own heap?
Gollum
@Gollum: No allocation is done if you use placement new. It just set `ptr` as `this` and calls the constructor.
KennyTM
@KennyTM, was talking about allocating a big buffer and then doing multiple `placement-new` for all the objects I need to allocate on that big-buffer(like n strings). (how would n objects get placed, it should have its own algorithm to fit those objects in - what about `fragmentation `
Gollum
@Gollum: Placement new has **nothing** to do with allocation. It just *places* `this` on the argument it takes than calls the constructor. In my answer it's the `malloc` line that's doing the allocation.
KennyTM
ok, thanks a lot. I think I need to read about it, I have doubts about placing more than one object on the `malloced` memory using `placement-new` which I guess is not possible.
Gollum
@Gollum: Why wouldn't it be possible? That's what `std::vector` *does*.
GMan
@GMan, correct me if wrong : let's say I put two `strings`, two `Some_Class_A` object, few other objects here and there. When I delete some object X, wouldn't it leave hole and thus fragmentation(if done for many-randomly). so my question is, how does it do all that management?assume, I did allocate 10K block and playing in that memory doing `placement-new` in it for all the objects.In case of vector, the object size is fixed and known at compile time.
Gollum
@Gollum: That's perfectly fine. You may need to play around with alignment issues but nothing is stopping you technically from putting a 10K (1 byte) objects or 5 (2K) objects or any combination you can think of into a 10K block or allocated space. Note: The block is allocated by you and thus it is your responsibility to manage the fragmentation and eventually release the memory as appropriate. As for vector the size is not known at compile time *that is why vector is so useful it is sized at runtime).
Martin York
@Martin York, Thank you very much for the explanation :-) . I meant the size of objects kept in `vector` not the size of vector itself.`std::vector<ClassA>` ----> size of ClassA is known at compile time
Gollum
@Gollum: What do you mean "a hole"? Firstly, you wouldn't `delete` anything made with placement new, you just call the destructor. Secondly, even if you could you'd still just have a hunk of memory, delete doesn't somehow steal part of it.
GMan
@GMan, **a hole:** if I placed 1000 object of 10 bytes in 10K memory I allocated with `malloc` and destroyed a few randomly from the which happen to be scattered in the middle of the block it will create small **holes** of 10 bytes (`fragmentation`) and when I go ask it to place some object of 11 bytes it will fail. so I was asking about how does the `placing` work internally. does it place these objects in contiguous memory or looks for these kind of holes too? I might not be explaining this well enough, confused enough people. apologies.
Gollum
@Gollum: No problem. :) Placing literally just puts an object where you say, so fragmentation is a totally separate issue.
GMan
+6  A: 

You can't call a constructor on an object; a constructor can only be called in the creation of an object so by definition the object can't exist yet.

The way to do this is with placement new. There's no need to cast your malloc return. It should be void * as it doesn't return a pointer to an A; only a pointer to raw memory in which you plan to construct an A.

E.g.

void* mem = malloc( sizeof(A) );

A* obj = new (mem) A();
obj->~A();

free(mem);
Charles Bailey
+2  A: 

Since you are using C++, falling back to malloc is unnecessary. You can write it in terms of operator new

int main() {
  if(A* obj = new (std::nothrow) A()) {
    delete obj;
    return 0;
  }
  return 1;
}

The nothrow version of new returns a null pointer if allocation fails, instead of throwing an exception.

Johannes Schaub - litb