Sign in to follow this  

deallocating a portion at the end of an array

This topic is 3457 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Am i right in thinking that it would work accurately to do the following for example: int * arr = new int[10]; delete [] (arr+5); and this would essentialy be the same as simply doing int * arr = new int[5]; that the delete operation works to deallocate the array after that point, and then doing. delete [] arr; would deallocate the rest of the array remaining.

Share this post


Link to post
Share on other sites
std::vector<int> arr(10);

arr.resize(5);
What you want however isn't possible, due to the way allocations work.

It's not impossible per-se, but the current specifications for new/delete do not do that.

- Pointers are evil
- Just because compiler allows you to do something with a pointer, doesn't mean it's sane

Share this post


Link to post
Share on other sites
Quote:
Original post by luca-deltodesco
delete [] (arr+5);


This is the part that doesn't work logically. It stores the array length somewhere in relation to the array it allocated (perhaps just before it) deleting a random part of the array makes it loose track of the array length.

Share this post


Link to post
Share on other sites
Quote:
Original post by stonemetal
This is the part that doesn't work logically. It stores the array length somewhere in relation to the array it allocated (perhaps just before it) deleting a random part of the array makes it loose track of the array length.


I figured that it work work more like a C style string with some sort of terminating entry that says 'this is the end of the array' as opposed to having a determined length.

Share this post


Link to post
Share on other sites
To perform a "size to fit" operation on an STL vector do the following:
vector<YourType>(yourVector).swap(yourVector);

resize() normally doesn't free memory, at least VS 2008 doesn't. You can verify this by checking the capacity().

Share this post


Link to post
Share on other sites
Quote:
Original post by Deaken Frost
To perform a "size to fit" operation on an STL vector do the following:
vector<YourType>(yourVector).swap(yourVector);

resize() normally doesn't free memory, at least VS 2008 doesn't. You can verify this by checking the capacity().


That doesn't do what you think it does.

The member version of swap in std::vector simply swaps arrays between the two vectors in constant time.

For example (much simplified):

namespace std
{
template<typename T>
class vector{
private:
T* dataPtr;
...
public:
...
void swap(vector<T> rhs)
{
T* temp = rhs.dataPtr;
rhs.dataPtr = dataPtr;
dataPtr = temp;
...
}
...
};
}


The whole point of vector is that you're not supposed to worry about the memory its using.

Share this post


Link to post
Share on other sites
Quote:

That doesn't do what you think it does.


I think it does. It creates a temporary vector, with the same elements as the original, and the size of the original (but not the capacity). It then does the quick pointer swap. Finally the temporary vector (which now holds the old data) is deallocated. The net effect is to "trim" the excess unused space.

It can be handy once you know the vector isn't going to grow anymore to free the potentially large wasted area in reserve. Its not something one should be doing most of the time, but it has its place, given that the std::vector interface has no way to explicitly remove the reserved space.


void print_vector_info(const std::vector<int> &vec)
{
std::cout << "Vector with size " << vec.size() << ", capacity " << vec.capacity() << '\n';
}

int main()
{
std::vector<int> vec;
for(int i = 0 ; i < 123 ; ++i )
{
vec.push_back(i);
}
print_vector_info(vec);
std::vector<int>(vec).swap(vec);
print_vector_info(vec);
}



Sample output:
Quote:

Vector with size 123, capacity 128
Vector with size 123, capacity 123

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Quote:

That doesn't do what you think it does.


I think it does. It creates a temporary vector, with the same elements as the original, and the size of the original (but not the capacity). It then does the quick pointer swap. Finally the temporary vector (which now holds the old data) is deallocated. The net effect is to "trim" the excess unused space.


If I understood you correctly: You're saying that a temporary std::vector of exactly the right size is created. That implies that the elements of the vector are copied into the correctly sized buffer. How can that operation satisfy the "constant time" requirement?

edit:

crap, I just realized you were swapping the vector with itself. Nothing to see here :)

Share this post


Link to post
Share on other sites
Quote:
Original post by luca-deltodesco
Quote:
Original post by stonemetal
This is the part that doesn't work logically. It stores the array length somewhere in relation to the array it allocated (perhaps just before it) deleting a random part of the array makes it loose track of the array length.


I figured that it work work more like a C style string with some sort of terminating entry that says 'this is the end of the array' as opposed to having a determined length.


This solution is first of all impossible: what value would you put there that could be guaranteed not to be a valid array element? Consider that 'new' works with general data types here.

And second, even if it did work, it would be needlessly slow (because the program would have to iterate at runtime just to free the memory).

Quote:
Original post by fpsgamer
Quote:
Original post by rip-off
Quote:

That doesn't do what you think it does.


I think it does. It creates a temporary vector, with the same elements as the original, and the size of the original (but not the capacity). It then does the quick pointer swap. Finally the temporary vector (which now holds the old data) is deallocated. The net effect is to "trim" the excess unused space.


If I understood you correctly: You're saying that a temporary std::vector of exactly the right size is created.


He is. Also, this is a standard idiom.

Quote:
That implies that the elements of the vector are copied into the correctly sized buffer. How can that operation satisfy the "constant time" requirement?


std::vector<T>::swap has a constant time requirement, but std::vector<T>::std::vector<T>(const std::vector<T>&) does not.

Share this post


Link to post
Share on other sites
Quote:
Original post by fpsgamer
If I understood you correctly: You're saying that a temporary std::vector of exactly the right size is created. That implies that the elements of the vector are copied into the correctly sized buffer. How can that operation satisfy the "constant time" requirement?


The swap operation runs in constant time. The creation of the temporary vector does not because it has to copy all the elements.

This method of trimming a vector was part of a Guru of the Week (http://www.gotw.ca/gotw/054.htm).

Share this post


Link to post
Share on other sites

This topic is 3457 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this