Thread: Quick question about memory allocation

  1. #31
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by anon View Post
    However, the references say:
    True, for primitives it would be slower. Nor can the compiler optimize the difference away.

    So, to gain anything from it I would have to overload the swap function for my type (and use using std::swap to make it choose the overload)?
    You gain if your element type has an efficient swap. The using declaration is not necessary, because iter_swap takes care of that. (You might want to use a using declaration for iter_swap, just in case you ever exchange the vector for something else.)

    However, then there would be unnecessary overhead for types that don't / cannot implement swap efficiently. Is there a way to make fast_erase choose swapping automatically if there is a swap method present for the type and use assignment otherwise?
    Not until we get Concepts in C+++09.
    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

  2. #32
    The larch
    Join Date
    May 2006
    Posts
    3,573
    True, for primitives it would be slower. Nor can the compiler optimize the difference away.
    And may-be large POD structs?

    You might want to use a using declaration for iter_swap, just in case you ever exchange the vector for something else.
    This would be about random access containers? Others have their specific erase methods.

    Not until we get Concepts in C+++09.
    So, until then I might just write two different erase functions, one using swap and other assignment, and leave it up to the user to choose the more efficient one.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #33
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Araanor View Post
    No, I don't want char. I don't even want an array of my_object. I want a region of memory where I can put my objects. CornedBee made a good post on how this is possible. I'd only be casting from void*, and only when new memory is allocated.
    The point was, if you want char (which you don't), then you allocate
    Code:
    char* p = new char[num];
    delete p;
    If you want my_obj (which you don't), then you do:
    Code:
    my_obj* p = new my_obj[num];
    delete p;
    And if you simply want void* (which basically char* is the same as), you do:
    Code:
    void* p = ::operator new(size);
    ::operator delete(p);
    The point is, you allocate and delete the memory with the same. You delete the same type. Don't allocate char and delete as void, or allocate my_obj and delete as char, or whatever. As long as you delete the original pointer (or another pointer, in either case, w/o changing the type), it works as intended.

    But it's also silly to allocate memory of a different type than you want. You don't want to allocate char when you want my_obj, or vice versa. Char works fine as a contigous memory block (because it's 1 byte), but you can use the raw operator new for that, I guess.
    Just so we're clear, yes?

  4. #34
    Registered User
    Join Date
    Nov 2007
    Posts
    14
    Yes.


    Here's how I do it now:
    Code:
    void *mMemory;
    ObjectType *mObjectArray;
    ...
    // Allocate memory
    mMemory = ::operator new(sizeof(ObjectType) * iInitialSize);
    mObjectArray = static_cast<ObjectType *> (mMemory);
    
    ...
    
    // Destruct all objects in the list
    for(int i = mObjectCount-1; i >= 0; --i)
    	mObjectArray[i].~ObjectType();
    
    // Free memory
    ::operator delete(mMemory);
    
    ...
    
    // Construct/add the object to the list
    new(mObjectArray + mObjectCount) ObjectType;
    mObjectCount++;

  5. #35
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you want objects of type ObjectType*, then allocate them like so. Why not?

    Code:
    mObjectArray = new ObjectType[iIntialSize];
    And also desutruct them with that type.
    Don't allocate void* and cast to a class -- that's just prone to errors of all kinds.

    You're walking a very dangerous route, and for what, may I ask?

  6. #36
    Registered User
    Join Date
    Nov 2007
    Posts
    14
    You know, I thought I asked if it would work. Does the cast produce undefined behaviour?

  7. #37
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No, it doesn't. That's pretty much how standard containers are implemented, except that the container never sees the void*. It simply stores a T*. The operator new allocation is then abstracted to the allocator system.
    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

  8. #38
    Registered User
    Join Date
    Nov 2007
    Posts
    14
    Ah, I see. Thank you.

  9. #39
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    What if you just allocate a raw chunk of memory, then use placement new inside that block of memory?
    I've never had a need to use Allocators or Placement New, but it sounds like that's what you're really looking for.

  10. #40
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Araanor View Post
    You know, I thought I asked if it would work. Does the cast produce undefined behaviour?
    The thing is, that while it may work, it's not really C++ -- it's more like C. If you're going to have type safety, then why not use it? There's no need to use void in C++, since we have templates. Just use T and allocate that with new.
    I don't really see why not? There's absolutely no reason (unless you're storing lots of different objects inside one container, in which case you need to be careful) not to.
    I tried to do that once. It wasn't very flexible and you'll have to be able to remember the type or the user of the class has to cast it once it gets its pointer.
    In either case, it is to be avoided, if possible.

    So do answer, because I'm not really sure. Are you storing multiple objects in one container or just one?
    Last edited by Elysia; 11-19-2007 at 12:27 AM.

  11. #41
    Registered User
    Join Date
    Nov 2007
    Posts
    14
    Optimization. The class uses an array to store objects, I found this to be the most efficient and clean way to implement it.
    The alternative would have been to do new ObjectType[someSize] when allocating. This would actually construct someSize objects before anything had been inserted into the list. Very ugly.

    It's a template class. The template is for the type of object to be stored. No mixing of object types. Everything is encapsulated in the class. Code on the outside knows nothing of the implementation, it only sees a list which isn't very unlike a bare bones std::vector.

  12. #42
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I see now... That makes it all clear.
    I'm still not sure if a single array to hold all data is more efficient than simply creating objects on the fly, though. Maybe you should do a test. Otherwise there would be no point is doing it your way.
    Anyway, it sounds like an interesting project, so good luck.

  13. #43
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's more efficient. Test the iteration and creation efficiency of a vector against a list, and you'll see.
    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

  14. #44
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I suppose that depends on the implentation.

  15. #45
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No. There is no way to implement a linked list so that it is more efficient at bulk allocation and iteration than a properly implemented vector.
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mutex and Shared Memory Segment Questions.
    By MadDog in forum Linux Programming
    Replies: 14
    Last Post: 06-20-2010, 04:04 AM
  2. POSIX Threads and dynamic memory allocation
    By PING in forum Linux Programming
    Replies: 1
    Last Post: 04-02-2009, 10:28 AM
  3. Pointer's
    By xlordt in forum C Programming
    Replies: 13
    Last Post: 10-14-2003, 02:15 PM
  4. Memory allocation at runtime?
    By electrolove in forum C Programming
    Replies: 6
    Last Post: 02-05-2003, 11:39 AM
  5. Yet another memory question
    By Dohojar in forum C Programming
    Replies: 5
    Last Post: 03-16-2002, 01:47 PM