问题
Yes, another realloc
vs. std::vector
question. I know what you're going to say, and I agree, forget manual memory allocation, and just use a std::vector
. Well unfortunately my professor has forbidden me to use anything from the STL for this assignment.
So yeah, I have a dynamic array of T
and I need it to be resizable, and I can't use std::vector
. I could return to the dark ages and do the whole thing with malloc
and family, but if I could use new
that would be totally awesome.
I've read plenty of threads where everyone said "no, you can't do it, use std::vector
", but they were all posted before August 2011, and I'm hoping against hope that something might have changed since the dawn of C++11. So tell me, am I in luck, or do I have to revert to C style memory allocation?
回答1:
You should avoid realloc
completely anyway, because you can't move around C++ objects like that.
- Use
buf = new unsigned char[sizeof(T) * capacity]
to create a new buffer - Cast the allocated
unsigned char *
toT *
and use theseT
-pointers from now on - Construct new elements via "placement
new
", as innew (&buf[i]) T(original_copy)
- To copy the buffer to a larger buffer, allocate the new one first, use
std::uninitialized_copy
(notstd::copy
), then destroy the elements in the old one usingbuf[i].~T()
and deallocate the old buffer usingdelete [] buf
.
All of this is assuming you don't have to worry about exception-safety, which is probably OK for the assignment.
Just be aware that in real-world code you'd have to guarantee exception safety and it's a lot more tedious than this.
回答2:
The problem with realloc
is that is may move the existing data to a different range of contiguous addresses. Should it need to do so, given it's a C function the data is copied without any nod to C++ object lifetime:
- copy/move constructors aren't used
- destructors aren't invoked afterwards for the source objects
This can cause fatal consequences - for example, when the objects being moved contain pointers/references that remain pointing at addresses in the memory area being vacated.
Sadly, normal malloc
implementations don't allow a callback hook allowing you to replace the memory-content-copying code with your own C++-safe implementation. If you're determined you could try to find a more flexible "malloc" library, but it's unlikely to be worth the hassle and risk.
Consequently, in the general case you should use new
to change your capacity, copy/move each object, and delete
the originals afterwards.
If you're certain your data is simple enough that a memcpy
-style relocation won't cause adverse consequences, then you can use realloc
(at your own risk).
来源:https://stackoverflow.com/questions/15061021/realloc-equivalent-in-c