开发者

C++ Deleting part of dynamic array

开发者 https://www.devze.com 2023-04-12 11:17 出处:网络
Say I have a dynamic array like: int* integers = new int[100]; Is there a way to delete only part of the array such as:

Say I have a dynamic array like:

int* integers = new int[100];

Is there a way to delete only part of the array such as:

int* integers2 = integers + 50;
delete[] integers2;

I want to not only delete everything 50 and beyond, but if I call another delete[] on the original integers array, then it would only delete the correct amount of memory and not try to delete the originally allocated amount and seg fault.

Why I want to do this: I have a data structure that is structured in levels of arrays, and I want to be able to create this data structure from a full array. So I want to be able to say

int* level1 = integers;
int* level2 = inte开发者_JAVA百科gers + 50;
int* level3 = integers + 100;

But when level 3 is no longer needed, the data structure will automatically delete[] level3. I need to know that this will behave correctly and not just destroy everything in the array. If it will then I need to just create new arrays and copy the contents over, but it would be nice to avoid doing that for performance reasons.

Edit: Everyone seems to be jumping to the conclusion that I just should use a dynamic resizing container (ie vector, deque) in the first place for my data structure. I am using levels of arrays for a good reason (and they aren't equally sized like I make it look like in my example). I was merely looking for a good way to have a constructor to my data structure that takes in an array or vector and not need to copy the original contents over into the new data structure.


No, this will not behave correctly. You can only delete[] pointers that you got from new[], else the results are undefined and bad things might happen.

If you really need the array to get smaller you have to allocate a new one and copy the contents manually.


Typically when memory gets allocated, there is some housekeeping stuff before the pointer.

i.e. houskeeping (pointer) data

You will mess that up.


int* integers2 = integers + 50;
delete[] integers2;

Will not work because new is created on int*, so space of 100 int has been assigned to integers, now integers2 is only a pointer to 50th location of integers, it has no space assigned to it of its own, so using delete will not delete rest of integers2, it'll only give erratic results.

What you can do is copy the first 50 in another array, and delete the previous array completely.

delete will only delete the pointer which has space assigned to it, using delete to another pointer pointing to the space assigned to first pointer will not delete any space assigned to the first pointer.

delete[] integers2 will not delete any space assigned to integers1 or any other pointer.


Dynamic allocators (like new) generally don't like you releasing part of the memory they gave you. If you use the <malloc.h> defined library functions malloc() and free() instead of new and delete, then you can use realloc(), though in most cases that you would care about the size difference it's just going to copy for you anyway.

Dynamically sizing containers generally use an exponential rule for resizing: if you run out of space, they (for example) double the allocation (and copy the old data over), if you remove data until you are using (for example) less than half the allocation they copy into a smaller allocation. This means you never waste more than half the memory, and the cost of copying per element added or removed is effectively constant. Implementing all of this is a pain in the ass, though, so just use std::vector and let it do it for you :).


No you can't do this with a fixed sized array allocated with new[]. If you want to have a dynamic array use one of the STL containers, such as std::vector.

0

精彩评论

暂无评论...
验证码 换一张
取 消