new[]. delete[]. resize[]?

Started by
7 comments, last by Krylloan 18 years, 10 months ago
Does anyone know how to resize an array constructed using new[], or get the current array size? eg

obj *x = new obj[5]; // 
x = renew obj[x,7]; // Construct two new objs.
printf("x has %d objs", x.size()); // Print the size of the array.
x = renew obj[x,3]; // Destruct four objs.
delete [] x; // Destruct the remaining three objs.


Secondly, does anyone know how to force-call a constructor or destructor on any object without calling the allocation functions or modifying the object's internal functions/data. eg

obj *x = (obj *)malloc(sizeof(obj)); // Manually allocate object.
x->obj();  // Manually call constructor.
x->~obj(); // Manually call destructor.
free(x);   // Manually free object.


I'd prefer to use the force-call method, as it allows me to manage my allocation easier. Thanks for all assistance. Simon.
Advertisement
a) allocate a new block, copy the data, delete the old block. No workaround. Use a std::vector - it does all that for you. The allocator template parameter lets you plug in different memory allocators.
b) new (ptr) Type; and ptr->~Type();
c) "manual" allocation in C++ is done with void* ::operator new(size_t) and void ::operator delete(void*), not malloc and free.

obj *x = (obj *) ::operator new(sizeof(obj)); // Allocate memorynew (x) obj;                                  // placement newx->~obj();                                    // Destructor call.::operator delete(x);                         // Deallocate memory
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by Krylloan
Does anyone know how to resize an array constructed using new[], or get the current array size?


Well you have to do it manually and you can't obtain the size directly from a C-style dynamic array, you should look into C++'s dynamic array std::vector.

Quote:Original post by Krylloan
Secondly, does anyone know how to force-call a constructor or destructor on any object without calling the allocation functions or modifying the object's internal functions/data.


To invoke the constructor only use the placement new operator if you use this you must explicitly invoke the destructor of user-defined types:

#include <new>struct foo {   int i;   foo(int j): i(j) {}};int main() {   void* buf = ::operator new(sizeof(foo)); // allocate only   foo* f = new(buf) foo(30); // construct only, placement new   f->~foo(); // destruct only, must be done for user-defined types   ::operator delete(buf); // de-allocate only}


You can do this with arrays but really you should look into std::vector, this is all very low-level and prone to bugs.
You can use realloc:
OBJECT* pObject = NULL;INT nObjectNum = 10;pObject = (OBJECT*)realloc(pObject, nObjectNum * sizeof(OBJECT));
If your objects have constructors/destructors, realloc() could leave you in deep doo-doo.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by WanMaster
You can use realloc:
OBJECT* pObject = NULL;INT nObjectNum = 10;pObject = (OBJECT*)realloc(pObject, nObjectNum * sizeof(OBJECT));


Quote:Original post by Fruny
If your objects have constructors/destructors, realloc() could leave you in deep doo-doo.


rephrase that, if you have non POD-types (Plain old data type, a technical term used in the standard) you are most certainly in deep doo-doo [grin].
Thanks. Almost works.
I'm having trouble getting the placement new to compile tho.

class obj {  public:     obj() : x(0) {}    ~obj() {}    int x;};int main() {    obj *x = (obj *) ::operator new(sizeof(obj)); // Allocate memory    new (x) obj;                                  // placement new    /* Other tries:      new (x) obj;      new (*x) obj;      new (x) obj();      new (*x) obj();      obj *y = new (x) obj;    */    x->~obj();                                    // Destructor call.    ::operator delete(x);                         // Deallocate memory    return 0;}


I also tried:
class obj {  public://     obj() : x(0) {}     obj(int y) : x(y) {}    ~obj() {}    int x;};int main() {    void* buf = ::operator new(sizeof(obj)); // allocate only    obj* f = new(buf) obj(5);                // construct only, placement new    f->~obj();                               // destruct only, must be done for user-defined types    ::operator delete(buf);                  // de-allocate only    return 0;}


Both fail to compile on the placement new.

Compiler Error:
37 ...\Main.cpp no matching function for call to `operator new(unsigned int, void*&)'
note ...\<internal>:0 candidates are: void* operator new(unsigned int)


As for vectors, I've looked at them a bit, but I'm using custom allocators and things get a little tricky there.


If it matters, I'm using DevC++ 4.9.9.2 in Windows/x86, which uses GCC.
#include <new>

Quote:As for vectors, I've looked at them a bit, but I'm using custom allocators and things get a little tricky there.


Study how the standard allocator class is implemented.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Awesome, very useful both of you. Solved my problem perfectly.

I promise to look at the standard allocator class implementation.



This topic is closed to new replies.

Advertisement