9

In C (or C++) I'm wondering if it's possible to partially deallocate a block of memory.

For example, suppose we create an array of integers a of size 100,

int * a = malloc(sizeof(int)*100);

and then later we want to resize a so that it holds 20 ints rather than 100.

Is there a way to free only the last 80*sizeof(int) bytes of a? For example if we call realloc, will it do this automatically?

  • I'm looking for a solution that doesn't require moving/copying the first 20 ints.
  • Alternatively, can you explain either why it would be bad if this were possible, or why the ability to do this wasn't included in either language?
Cam
  • 14,930
  • 16
  • 77
  • 128

3 Answers3

15

You can use realloc, but you should definitely consider using STL containers instead of manually allocating memory.

On Freund
  • 4,376
  • 2
  • 23
  • 30
  • 1
    Doesn't realloc copy the array and then free the original? – Cam Dec 15 '10 at 07:12
  • 4
    @Cam, no. It is allowed to (and often will) shrink the existing region. – Matthew Flaschen Dec 15 '10 at 07:13
  • 4
    @watson1180: Right, but that alone means nothing. In principle realloc could be implemented to take O(n!^99) time and always allocate 500 times the necessary memory, but we certainly don't factor that in when making decisions involving realloc. – Cam Dec 15 '10 at 07:59
  • 3
    @watson, what real implementation of `realloc` doesn't return memory to the system? Note that either shrink in place or move, copy, free old will return memory. – Matthew Flaschen Dec 15 '10 at 08:24
3

We prefer RAII containers to raw pointers in C++.

#include <vector>

// ...

{
    std::vector<int> a(100)
    // ...
    std::vector<int>(a.begin(), a.begin() + 20).swap(a);
}
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • 4
    It should be noted that this doesn't really "partially deallocate memory." This allocates a new block of the desired size, copies the contents from the original block, and then frees the original block. – James McNellis Dec 15 '10 at 07:11
  • 1
    resize() does not have to adjust the allocated memory. Even clear() does not have to. – Chris Hopman Dec 15 '10 at 07:49
  • Agree. resize doesn't have to free memory. On all implementation I know resize leaves the capacity of vector unchanged. – watson1180 Dec 15 '10 at 08:10
2

I would prefer using a std::vector. Let's enable C++0x:

std::vector<int> vec(20);
vec.reserve(100);

// do something

vec.shrink_to_fit();

From n3092 (not the so final draft, I need to get a fresh copy on this PC):

void shrink_to_fit();

Remarks: shrink_to_fit is a non-binding request to reduce memory use. [ Note: The request is non-binding to allow latitude for implementation-specific optimizations. —end note ]

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722