Is there a way to expand a dynamic memory array in C++?
Is there a way to expand a dyn开发者_如何学编程amic memory array? like this:
int *a = new int[5];
*a = new int[2];
Is this legal?
You cannot expand this type of a dynamic memory array. You can use malloc
and realloc
though if you need this facility but I would advice against that and suggest including <vector>
and using std::vector
instead. It has a resize
method.
Also, what you described won't compile. The following will:
1: int *a = new int[5];
2: a = new int[2];
The above will allocate two memory blocks, neither of which will be destroyed. Second line will simply assign a new array to the same int *a
pointer. When an allocated memory stops being referenced by any pointer, this is called a memory leak. The above code loses any reference to new int[5]
and there is no way to free this memory to the operating system.
Although this is not a very practical example, there are multiple ways to resize an array/vector. As it is usually practical to increase the array size, I will do just this:
{ // C++ vector on the stack (although internally vector uses memory from the heap)
std::vector<int> a(1024);
// do smth
a.resize(4096); // note: this does not always reallocate
// do smth else
}
{ // C++ everything on the heap
std::vector<int> *a = new std::vector<int>(1024);
// do smth
a->resize(4096); // note: this does not always reallocate
// do smth else
delete a;
}
{ // C style
int *a = (int*)malloc(1024*sizeof(int));
// do smth
a = realloc(a, 4096*sizeof(int));
// do smth else
free(a);
}
It is worth to note that realloc
does not do anything smart. All it does is:
- Allocate new memory block
malloc
- Copy data from old memory block to new memory block
memcpy
- Free old memory block
free
- Return new memory block
You can certainly expand an array, but you need to take care of copying the contents and of freeing the old array (your code, apart from being incorrect syntax, shrinks the array, btw.).
Which is exactly how std::vector
works, just you don't have to care.
So basically, having int *a
already allocated, what needs to happen is something like:
{
std::unique_ptr<int[]> d(a);
a = new int[desired_new_size];
for(unsigned int i = 0; i < min_old_size_and_new_size; ++i)
a[i] = d[i];
}
Note that strictly speaking "expanding" never really expands the array, but replaces it with another bigger one (that is true for any containers offering the same functionality too). But this is transparent to any code using the pointer later, nobody will know.
You should never use realloc
(or any other C memory allocation functions) in combination with memory allocated or freed by operator new
and delete
(or new[]
and delete[]
) as pointed out above.
This may work (and usually will), but it's conceptually wrong, and it's pure luck (unknown implementation detail) if it does not crash.
精彩评论