Anton Daneyko
Anton Daneyko

Reputation: 6503

Is there a way to free only a part of the dynamically allocated array in C\C++ (shrink existing array)?

In a program I allocate a huge multidimensional array, do some number-crunching, then only the first part of that array is of further interest and I'd like to free just a part of the array and continue to work with the data in the first part. I tried using realloc, but I am not sure whether this is the correct way, given I must preserve the data in the array and preferably avoid copying of that chunk in memory.

#include <cstring>
#include <cassert>
#include <iostream>

using namespace std;

void FillArrayThenTruncate(char* my_array, const int old_size, int* new_size);

int main() {
    const int initial_size = 1024*1024*1024;
    char* my_array = static_cast<char*>(malloc(initial_size));
    assert(my_array);
    int new_size;
    FillArrayThenTruncate(my_array, initial_size, &new_size);
    for(int i = 0; i < new_size; ++i) cout << static_cast<int>(my_array[i]) << endl;
}

void FillArrayThenTruncate(char* my_array, const int old_size, int* new_size) {
    //do something with my_array:
    memset(my_array, 0, old_size);
    for(int i = 0; i < 10; ++i) my_array[i] = i % 3;
    //cut the initial array
    *new_size = 10;
    void* new_array = realloc(my_array, *new_size);
    cout << "Old array pointer: " << static_cast<void*>(my_array) << endl;
    cout << "New array pointer: " << new_array << endl;
    my_array = static_cast<char*>(new_array);
    assert(my_array != NULL);
}

UPDATE:
* Please do not bother to suggest to use STL. The question is about C array.
* Thanks to "R Samuel Klatchko" for pointing out the bug in the code above.

Upvotes: 3

Views: 1901

Answers (3)

Cogwheel
Cogwheel

Reputation: 23217

I assume you're using this for learning... otherwise I'd recommend you look into std::vector and the other STL containers.

The answer to the title question is No. You have to either compact the existing elements, or you need to allocate new space and copy the data you want. realloc will either extend/contract from the end or allocate new space and copy the existing data.

If you're working with such a large data set, you might as well just have a collection of chunks rather than a monolithic set. Maybe avoid loading the whole thing into ram to begin with if you only need certain parts.

Upvotes: 5

DevSolar
DevSolar

Reputation: 70303

For C++, use STL containers instead of handling your memory manually. For C, there is realloc().

Upvotes: 3

R Samuel Klatchko
R Samuel Klatchko

Reputation: 76541

Yes, if you allocate with malloc, you can resize with realloc.

That said, realloc is allowed to move your memory so you should be prepared for that:

// Only valid when shrinking memory
my_array = realloc(my_array, *new_size);

Note that if you are growing memory, the above snippet is dangerous as realloc can fail and return NULL in which case you will have lost your original pointer to my_array. But for shrinking memory it should always work.

Upvotes: 2

Related Questions