Есть ли способ освободить только часть динамически размещенного массива в C \ C ++ (уменьшить существующий массив)? - PullRequest
3 голосов
/ 01 июля 2010

В программе я выделяю огромный многомерный массив, выполняю некоторое сокращение числа, тогда только первая часть этого массива представляет дальнейший интерес, и я хотел бы освободить только часть массива и продолжить работу сДанные в первой части.Я пытался использовать realloc, но я не уверен, что это правильный путь, поскольку я должен сохранить данные в массиве и желательно избегать копирования этого фрагмента в памяти.

#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);
}

ОБНОВЛЕНИЕ:
* Пожалуйста, не предлагайте использовать STL.Вопрос о массиве C.
* Спасибо "R Samuel Klatchko" за указание на ошибку в приведенном выше коде.

Ответы [ 3 ]

4 голосов
/ 01 июля 2010

Я предполагаю, что вы используете это для обучения ... в противном случае я бы порекомендовал вам заглянуть в std :: vector и другие контейнеры STL.

Ответ на заглавный вопрос - нет. Вы должны либо сжать существующие элементы, либо выделить новое пространство и скопировать нужные данные. realloc будет либо расширяться / сокращаться с конца, либо выделять новое пространство и копировать существующие данные.

Если вы работаете с таким большим набором данных, у вас может быть просто набор фрагментов, а не монолитный набор. Может быть, сначала не загружайте все это в оперативную память, если вам нужны только определенные детали.

3 голосов
/ 01 июля 2010

Для C ++ используйте контейнеры STL вместо ручной обработки памяти.Для C есть realloc().

2 голосов
/ 01 июля 2010

Да, если вы выделите с помощью malloc, вы можете изменить размер с помощью realloc.

При этом realloc разрешено перемещать вашу память, поэтому вы должны быть готовы к этому:

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

Обратите внимание, что если вы увеличиваете объем памяти, приведенный выше фрагмент опасен, так как realloc может завершиться с ошибкой и вернуть NULL, в этом случае вы потеряете свой первоначальный указатель на my_array.Но для сокращения памяти это всегда должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...