Archived

This topic is now archived and is closed to further replies.

MARS_999

realloc what is the equivalent in C++ with new?

Recommended Posts

I am using new to allocate memory for my textures. Instead of using new and calling delete for each texture how can I allocate memory once and like with c, I think its realloc(), reallocate memory for a new size so I don''t fragment my memory? Thanks

Share this post


Link to post
Share on other sites
Not really due to you can''t mix and match malloc or C dynamic allocation methods with C++ new and delete dynamic allocation. I was wondering how C++ does it if it has some keyword or C++ function like realloc? Thanks

Share this post


Link to post
Share on other sites
quote:
Original post by MARS_999
Not really due to you can''t mix and match malloc or C dynamic allocation methods with C++ new and delete dynamic allocation. I was wondering how C++ does it if it has some keyword or C++ function like realloc? Thanks

No, it does not.

Share this post


Link to post
Share on other sites
There is no "renew" or other equivalent to realloc in C++. This really isn''t a big deal, though. Just allocate your new buffer, use memcpy to copy the contents of the old buffer to the new one, and then delete the old buffer. This is functionally equivalent to what realloc does, anyways.

Share this post


Link to post
Share on other sites
I was told doing new and delete and new and delete will fragment memory??


int *p = new int[100];
//do stuff with p[]


delete []p;

int *p = new int[1000];
//do stuff again


delete []p;


now you get the idea? now do that for e.g. 20x or 100x
will that fragment memory???

Thanks

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
The equivalent of using malloc/realloc in C is to use std::vector in C++.

Anyway, I wouldn''t worry about fragmentation. Realloc can''t do anything more than what the library can do with a delete and a successive new. In fact, realloc needs to preserve the block contents, which may be a bit of a disadvantage (and certainly causes an unnecessary copy if you want to re-write the block).

Don''t optimize until you know that you have to. Fragmented heaps are REALLY hard to come by on modern computers (although it does happen in really big projects. Like, REALLY big)

Share this post


Link to post
Share on other sites
quote:
Original post by MARS_999
I was told doing new and delete and new and delete will fragment memory??


int *p = new int[100];
//do stuff with p[]


delete []p;

int *p = new int[1000];
//do stuff again


delete []p;


now you get the idea? now do that for e.g. 20x or 100x
will that fragment memory???

Thanks




As the AP said, you really don't need to worry about this. The big thing is make sure you don't create any leaks.

What you showed also doesn't really pertain to the OP since we are talking about expanding an array not repeatedly newing and deleting.

In any event, "expanding" you array size does result in creation of a new larger buffer and copying the contents of the old one over, no matter what.

If you find yourself frequently enlarging your buffer, you should probably use a different strategy anyways, such as using vectors or allocating a buffer that you believe to be large enough and then use that. If you use the latter solution, you will need to check your bounds. Assumptions can be dangerous.


[edited by - jeeky on August 31, 2003 12:07:10 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
The equivalent of using malloc/realloc in C is to use std::vector in C++.



Not quite, but almost. std::vector does give you risizable arrays and overloaded [], but you can''t treat the vector as a contiguous memory block.

For example, you can''t use a std::vector in OpenGL vertex array calls. This is the biggest problem with std::vector that I see in graphics programming. If anyone knows a way around it, let me know.

Share this post


Link to post
Share on other sites
quote:
Original post by Namethatnobodyelsetook
You could always define your own ''new''s that can perform a realloc operation behind the scenes. That''s the only C++ friendly way I can think of... and having thought of it, I think I''m off to code myself up one.



Thinking about it, this ISN''T such a great idea, as the reallocing new will still call constructors for the previously existing members...

Do you have any reason not to use realloc, and placement new on each new member, or manually call destructors when shrinking? I''ve done this technique before for a dynamic array and it works perfectly.

Share this post


Link to post
Share on other sites
quote:
Original post by Namethatnobodyelsetook
quote:
Original post by Namethatnobodyelsetook
You could always define your own ''new''s that can perform a realloc operation behind the scenes. That''s the only C++ friendly way I can think of... and having thought of it, I think I''m off to code myself up one.



Thinking about it, this ISN''T such a great idea, as the reallocing new will still call constructors for the previously existing members...

Do you have any reason not to use realloc, and placement new on each new member, or manually call destructors when shrinking? I''ve done this technique before for a dynamic array and it works perfectly.



I just don''t want to use C dynamic allocation functions. I am using C++ new and delete. I was just wondering if C++ had anything and now I know it''s no. Reason is I just wanted to use one pointer that was allocated with new for my texture loader and reallocate memory for different sizes and bit depths. =) But I am going to keep on doing what I have been each call to LoadTGA() I call new and delete it. Then if I call the function again I do it all over again. I have a Class for loading .tga files. Thanks

Share this post


Link to post
Share on other sites
You could use placement new, and call realloc, and/or overload new for the texture class, and provide an overload that takes a second parameter telling it to realloc.

...
quote:
Original post by jeeky
Not quite, but almost. std::vector does give you risizable arrays and overloaded [], but you can''t treat the vector as a contiguous memory block.


Actually you can, all professional vector implementations provide a continuous memory block. In C++0x it will be a requirement.

&*vec.begin() yields a C-compatible pointer to the first element.

Share this post


Link to post
Share on other sites
I think jeeky said it... just allocate the amount of memory that will hold the biggest image and use it for all of them. There is no reason to delete it between uses.
Anyway, why don''t you want to use C allocation functions. I know that alot of C++ books preach the evils of malloc and free, but in this case the memory does not need to be initialized there is no reason to fear malloc.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
Anyway, I wouldn't worry about fragmentation. Realloc can't do anything more than what the library can do with a delete and a successive new. In fact, realloc needs to preserve the block contents, which may be a bit of a disadvantage (and certainly causes an unnecessary copy if you want to re-write the block).


quote:
Original post by jeeky
In any event, "expanding" you array size does result in creation of a new larger buffer and copying the contents of the old one over, no matter what.


If there was no benefit of realloc over a malloc() and memcpy(), realloc wouldn't exist. In fact - try implementing your own malloc sometime, it's a really good exercise for insight into how memory management really works. Unix systems provide the sbrk() system call which is used to implement malloc. You'll see that it's quite possible to increase the size of allocated blocks.

The easiest way to find out is to confirm it yourself.
int *a = malloc(4);
int *b = realloc(a, 8);
return a == b;


The "new" block has the same adress as the "old" block. Also, you shouldn't be doing this kind of stuff at all if you didn't want to keep the contents of the memory.

As such, realloc is potentially enormously more efficient than new/copy/delete, since you don't need to run a few thousand constructors/assignment operators to shift memory around.

/Stary

[edited by - Stary on September 1, 2003 8:56:52 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Stary
quote:
Original post by Anonymous Poster
Anyway, I wouldn''t worry about fragmentation. Realloc can''t do anything more than what the library can do with a delete and a successive new. In fact, realloc needs to preserve the block contents, which may be a bit of a disadvantage (and certainly causes an unnecessary copy if you want to re-write the block).


quote:
Original post by jeeky
In any event, "expanding" you array size does result in creation of a new larger buffer and copying the contents of the old one over, no matter what.


If there was no benefit of realloc over a malloc() and memcpy(), realloc wouldn''t exist. In fact - try implementing your own malloc sometime, it''s a really good exercise for insight into how memory management really works. Unix systems provide the sbrk() system call which is used to implement malloc. You''ll see that it''s quite possible to increase the size of allocated blocks.

The easiest way to find out is to confirm it yourself.
int *a = malloc(4);
int *b = realloc(a, 8);
return a == b;


The "new" block has the same adress as the "old" block. Also, you shouldn''t be doing this kind of stuff at all if you didn''t want to keep the contents of the memory.

As such, realloc is potentially enormously more efficient than new/copy/delete, since you don''t need to run a few thousand constructors/assignment operators to shift memory around.

/Stary

[edited by - Stary on September 1, 2003 8:56:52 AM]



Hold on. With new and delete their is no constructor or deconstructors being called for simple variables like int, float ect... now with objets yes. Calling new or delete with int is like calling malloc or free.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Maybe you are making it hard for yourself by having a single class containing both the texture definition and the pixel data. If your data structure contains some form of header {width,height,bits,colortype} and an area for the picture data, then you could use new/delete on the header and malloc/free/realloc on the data pointer the header class would contain.

Share this post


Link to post
Share on other sites