Archived

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

Bullmax

"realloc()" behavior with "new"

Recommended Posts

Hello camarades, I have a basic C to C++ question. By using the "malloc()", "calloc()", "realloc()" family, I can allocate memory. With "realloc()", I can pass a pointer that points to a previously allocated memory block and I would be able to resize the memory block by allocating only the offset required (I think so). The problem is that it does not call the constructor if I allocate memory for a class instance. I know that "new" will call the constructor if the class instance has one, but I don''t know if "new" will have the same behavior as "realloc()". Does someone knows if it the same of if I can simulate this. Maybe with the "new" operator overloading or .... I don''t know.
/* Bullmax */ ------------- Reality has many forms : good and evil, black and white, yin and yang.

Share this post


Link to post
Share on other sites
I''m pretty sure realloc just wraps the behavior of deleting the memory, allocating a new block, and copying the old contents into the new buffer - nothing special. If you have memory you want to reallocate, new the new memory, copy the contents of the buffer up to the shorter of the two buffers, and delete the old block. Make a function out of it, but don''t go overloading the new operator.

Share this post


Link to post
Share on other sites
quote:
Original post by Zipster
I''m pretty sure realloc just wraps the behavior of deleting the memory, allocating a new block, and copying the old contents into the new buffer - nothing special.

Not necessarily - that''s the beauty of it. It might do this, but it might also simply allocate more memory at the end of the existing block, which is much more efficient; if there isn''t sufficient memory there, it will attempt to allocate an entirely new block and copy the data there. (... All according to the MSDN docs.)

Share this post


Link to post
Share on other sites
That is true, but you have to ask yourself what practical use it really has. It might keep the same pointer, it might not. You can't tell before you call it.

So what you do is assign the return value to the same pointer.
Sure, it saves you a few lines of code, but since you never know what's going to happen when you call it, in effect, there's no advantage to using realloc() over a call to new[] and then an assignment.

The other option, if you're dead set on using realloc() is to use placement new on each element of your realloc()'ed block.

But then, that's even MORE lines of code. Personally, I'd just suggest doing this:

Object* tmp = new Object[count];
for(int i = 0; i < count; ++i)
tmp[i] = old[i];
delete [] old;
old = tmp;


But then again , if you're gonna go to that much trouble, just use a std::vector, and all your problems are solved.

[edited by - daerid on January 28, 2003 12:19:29 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Bullmax
The problem is that it does not call the constructor if I allocate memory for a class instance. I know that "new" will call the constructor if the class instance has one, but I don''t know if "new" will have the same behavior as "realloc()".

An object''s size is fixed at compile-time, so it is meaningless to perform a runtime realloc.

Share this post


Link to post
Share on other sites
SabreMan :
I wanted to create object instances into memory, not resize the size of my class.

daerid:
Is there a chance that your code could erase my old memory. I mean if the tmp block would overlapp the old block, you could lose data, no ?


0x4500 | 0x4600 | 0x4700 | 0x4800 | 0x4900 | 0x5000
---------------------------------------------------
OLD X X X X

TMP X X X X


Could this happen in memory ? If yes, it's dangerous....

*I mean the copy operation from "old" to "tmp" could make lose data if it's overlapping. Try the algorithm on this "graphic"

[edited by - Bullmax on January 29, 2003 7:54:05 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Bullmax
SabreMan :
I wanted to create object instances into memory, not resize the size of my class.

I see. Look up "placement new" in your favourite C++ reference.

Share this post


Link to post
Share on other sites
quote:
Original post by Bullmax
daerid:
Is there a chance that your code could erase my old memory. I mean if the tmp block would overlapp the old block, you could lose data, no ?

That''s not possible, and would be quite insane. You really should learn about the standard containers, such as std::vector, which do all manner of stuff behind the scenes such as you are describing. For instance, vector has a reserve() member, which pre-allocates storage, and then uses placement new to perform in-place construction of items added to the vector. Chances are vector (or some other standard container) already does for your needs.

Share this post


Link to post
Share on other sites
Thanks for all these answer !
I''ll give a try and there will be feedback. hang on



/* Bullmax */
-------------
Reality has many forms : good and evil, black and white, yin and yang.

Share this post


Link to post
Share on other sites
I've read Thinking in C++ about "new" placement. Interesting, but I don't like the fact that I must destroy my objects explicitly by calling the destructor myself...

I thinked about it and realized that the technique of daerid would never cause mempory overlapping because new give you a completely free chunk of memory. If not, it would be insane... [as SabreMan said]

So I think that I would rather use is technique that consist of creating a new chunk representing the "reallocation", copying the old chunk content into the new chunk content and then destroy the old chunk.

There is a drawback...(as always). If I have a huge memory chunk (I don't have a representative example) to resize, I would need a ton of free memory to create the new chunk and keeping in mind that I will have to copy the whole old chunk into the new chunk... argh!

I don't think that I will encounter this catastrophic scenario, but... I don't like systematic scenario rejection when it is possible.

Am I taking a good decision ?



/* Bullmax */
-------------
Reality has many forms : good and evil, black and white, yin and yang.

[edited by - Bullmax on January 30, 2003 1:30:13 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Bullmax
I''ve read Thinking in C++ about "new" placement. Interesting, but I don''t like the fact that I must destroy my objects explicitly by calling the destructor myself...



You don''t have a choice. The object might have to inform other objects that it has moved, or it might internally hold pointers

quote:

So I think that I would rather use is technique that consist of creating a new chunk representing the "reallocation", copying the old chunk content into the new chunk content and then destroy the old chunk.



If you use your class'' copy constructor, you''ll be fine, otherwise you''ll get in big trouble very soon.

quote:

There is a drawback...(as always). If I have a huge memory chunk (I don''t have a representative example) to resize, I would need a ton of free memory to create the new chunk and keeping in mind that I will have to copy the whole old chunk into the new chunk... argh!



realloc suffered from exactly the same problem.

quote:

I don''t think that I will encounter this catastrophic scenario, but... I don''t like systematic scenario rejection when it is possible.



You will, one day, run out of memory. It is a certainty. Be prepared.

quote:

Am I taking a good decision ?



No. Learn to use standard containers. Only when they don''t fit the bill should you start mucking with manual memory management.



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites
quote:
Original post by Bullmax
Am I taking a good decision ?

You''re making life unccecessarily hard for yourself. Forget about how you would do it with C, you''re programming in C++ now. Get a hold of Accelerated C++, and work through it.

Share this post


Link to post
Share on other sites