![]() |
| | #1 |
| Registered User Join Date: Aug 2009
Posts: 8
| resize array of objects An example of code to illustrate the problem reads: Code: class Myclass
{
public:
void* operator new[](size_t);
};
void* Myclass::operator new[](size_t size)
{
void *storage = malloc(size);
if(NULL == storage) {
throw "allocation fail : no free memory";
}
return storage;
}
int main(void)
{
Myclass *MyArrayOfMyClass,*ExpandedArrayMyOfClass;
MyArrayOfMyClass = new Myclass[10];
// I need to resize my array of objects
ExpandedArrayMyOfClass = (Myclass*)realloc (MyArrayOfMyClass, sizeof(Myclass)*((size_t)(20)) );
// <- So this is unsafe, because I allocate 4 bytes too less.
// and the real base of the memoryblock of MyArrayOfMyClass is &(((char*)MyArrayOfMyClass)[-4])
}
How to get the real memory address and required length for MyArrayOfMyClass? On my system, memory is 16 byte alligned, so any ptr should have an address ending on 0 (example 0x1001c0), but can I rely on this? And I don't want to use std::vector |
| isgoed is offline | |
| | #2 | |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,354
| Quote:
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | |
| laserlight is online now | |
| | #3 |
| Registered User Join Date: Aug 2009
Posts: 8
| I want to be able to save my objects to disk in a way that handles arrays, classes and data uniformly. Since a vector is a struct I have to access the internal pointers of the array. The vector struct also requires quite some memory (32 bytes on 64 bit), which is a waste if you have many small arrays. And lastly: (I am not so sure about this point) in the vector implementation it cannot be controlled how much memory is allocated and the size of the allocated memory cannot be predicted (you might request it with vector->capacity() though) |
| isgoed is offline | |
| | #4 | |||
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,354
| Quote:
Quote:
Quote:
If you really do want to implement a dynamic array, I suggest that you look at the last option mentioned in that article that you linked to: placement new with a buffer. The tricky parts of needing to construct and destroy explicitly (and perform copying) would be hidden by your class interface.
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | |||
| laserlight is online now | |
| | #5 |
| and the hat of sweating Join Date: Aug 2007 Location: Toronto, ON
Posts: 3,120
| Have you actually tried using std::vector and done some performance measurements to verify that the vectors are actually a bottleneck for you?
__________________ "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008 |
| cpjust is offline | |
| | #6 |
| Registered User Join Date: Aug 2009
Posts: 8
| Well I have come up with a solution: I just don't call new and delete any more, but use my own memory allocation and initialization. You can't invoke a constructor, but you can just use a member function (although it is said that it isn't proper to call a member function of an object that is not initialized). anyways.. code like this: Code: // create my class
MyClass *MyInstance = malloc(sizeof(MyClass));
MyInstance->initMyClass(argument);
// resize my class
arraylength = 10;
MyInstance = (MyClass*)realloc ((void*)MyInstance, sizeof(MyClass)*arraylength);
for(i=1;i<arraylength;++i){
MyInstance[arraylength].initMyClass(argument);}
// delete my class
for(i=0;i<arraylength;++i){
MyInstance[i].deleteMyClass();}
free(MyInstance);
MyInstance = 0;
Laserlight, thanks for the Boost.Serialization suggestion. This really sounds like the answer to everything related to resource management (But I need more I think that, now that i know that I can cast memory to an object, I can also cast memory to a vector and lose the need to copy the memory. |
| isgoed is offline | |
| | #7 | ||||
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,354
| Quote:
Quote:
Quote:
Quote:
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | ||||
| laserlight is online now | |
| | #8 | ||
| Registered User Join Date: Aug 2009
Posts: 8
| Quote:
Quote:
Code: X<T>* pobj = (X<T>*)ptr; //step 1: cast void * to the appropriate type *pobj=X<T>(); //create a temp, assign it to the raw buffer But as far as i can tell they are only assigning a value to a ptr (casting). Where is the object created? I know that "=" also is a constructor in C++, but not if you assign ptrs instead of objects. So what's going on? | ||
| isgoed is offline | |
| | #9 | |||
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,354
| Quote:
Code: int i = 0; int j = i++ + i++; Quote:
Quote:
Code: static X<T>* construct(void* ptr)
{
X<T>* pobj = (X<T>*)ptr; // step 1: cast void * to the appropriate type
*pobj = X<T>(); // create a temp, assign it to the raw buffer
return pobj;
}
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | |||
| laserlight is online now | |
| | #10 | ||
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,099
| Quote:
Undefined means that you cannot predict what will happen and that anything can happen. Consider this: Code: int main()
{
int* p;
*p = 50;
}
And what about: Code: int main()
{
int n[5];
n[5] = 50;
}
That's the meaning of undefined. Don't ever do it.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| ||
| Elysia is offline | |
| | #11 | |
| Registered User Join Date: Aug 2009
Posts: 8
| Quote:
Code: // create my class
MyClass *MyInstance;
MyInstance = new(malloc(sizeof(MyClass))) MyClass();
// resize my class
MyClass *MyDummy;
int arraylength = 10;
MyInstance = (MyClass*)realloc ((void*)MyInstance, sizeof(MyClass)*arraylength);
for(i=1;i<arraylength;++i){
MyDummy = new(&MyInstance[i]) MyClass();}
// delete my class
for(i=0;i<arraylength;++i){
// Explicitly call the destructor for the placed object
MyInstance[i].~MyClass();}
free((void*)MyInstance);
MyInstance = 0;
What is "placement new" and why would I use it?. Note that you are explicitly calling the destructor here. But you have to be careful here; the article mentioned above will point out some pittfalls. And I want to make clear that you should be careful not to use placement new and new alongside each other. They could allocate memory differently (and there are many forms of new). A real insightfull article is this one (on the same site) [11.14] Is there a way to force new to allocate memory from a specific memory area?. You cannot call a constructor explicitly, but you can call a destructor explicitly? The thing is that if you allow a programmer access to a class before it is initialized, he could access (private) members which are not yet available, in order to safeguard against mistakes. This particularly holds for objects with a virtual table/pointer as mentioned in the above article (a simple test shows that a class with virtual members will be 4 bytes longer). But since all this happens in the compiler and the compiler only makes code that might as well have been written in C, there is nothing stopping you from writing your own constructor. If you know what your object will look like, calling a member function before it is initialized is perfectly safe. This is the case if your object is a C-code compatible struct. Note that it is also not required to call your destructor, it is just common use. Having said that, the code in my 6th post might be preferable in many cases. Fiddling with new and delete causes a lot of exceptions that easily lead to errors (see the articles for the solutions). The only thing that can go wrong with using unitialized objects is a failed call to malloc. Furthermore the new and delete call actually execute multiple lines of code, resulting in a performance hit and obfuscating code. | |
| isgoed is offline | |
| | #12 | ||
| The larch Join Date: May 2006
Posts: 3,082
| I have no idea what you are talking about. In your code there is a potential memory leak with the realloc (if it fails it returns NULL and doesn't release original memory). Quote:
__________________ I might be wrong. Quote:
| ||
| anon is offline | |
| | #13 | ||
| Registered User Join Date: Aug 2009
Posts: 8
| Then why are you replying? Quote:
Quote:
| ||
| isgoed is offline | |
| | #14 | |||||
| The larch Join Date: May 2006
Posts: 3,082
| Quote:
Quote:
Quote:
I suspect that what the FAQ demonstrates will be encapsulated away, so the user of that code never needs to worry about these things again. Another thing is, you'll do all this when you really know what you are after. Quote:
__________________ I might be wrong. Quote:
| |||||
| anon is offline | |
| | #15 | |
| Cat without Hat Join Date: Apr 2003
Posts: 8,439
| Quote:
- It is a reference. - It has a user-defined constructor, copy assignment operator, or destructor. - It has a base class. - It has a virtual function. - It has a non-static member that is not a POD itself. If any of these apply, the object is not a POD, and it's completely undefined what happens if you access it without calling the constructor first. The core notion of a POD is that you are allowed memcpy it somewhere else, and the target memory contains a valid copy of the original object. You *must not* use memcpy (or memmove or realloc) on any other object. (These rules will change in C++0x, which introduces the notion of a "standard layout type".)
__________________ All the buzzt! CornedBee"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code." - Flon's Law | |
| CornedBee is offline | |
![]() |
| Tags |
| array, new[], objects, realloc, resize |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| array of objects | adam_no6 | C++ Programming | 2 | 04-04-2007 07:59 AM |
| Returning an Array of Pointers to Objects | randomalias | C++ Programming | 4 | 04-29-2006 02:45 PM |
| accesing data in class objects (array of pointers to objects) | agony | C++ Programming | 4 | 10-16-2003 11:26 AM |
| Struct *** initialization | Saravanan | C Programming | 20 | 10-09-2003 12:04 PM |
| Adding objects to an array | Unregistered | C++ Programming | 3 | 11-27-2001 09:24 AM |