Могу ли я использовать std :: realloc для предотвращения избыточного выделения памяти?

0

Мне нужно выделить пространство для временного массива один раз за итерацию. Я пытаюсь использовать realloc каждую итерацию для оптимизации использования памяти. Как это:

int *a = (int*)std::alloc(2 * sizeof(int));
for(int i=0; i<N; ++i) 
{
    int m = calculate_enough_size();
    a = (int*)std::realloc(m * sizeof(int));
    // ...
}
std::free(a);

N - большое число, например, 1000000. Для каждой итерации есть пример значений m: 8,2,6,10,4,8

Могу ли я делать правильно, когда я перераспределить на каждой итерации? a Предотвращает ли это избыточное выделение памяти?

  • 0
    Вам нужно поддерживать содержимое массива на протяжении итераций?
  • 0
    Вы можете сохранить текущий размер сквозных итераций и только перераспределить, когда вам нужно больше размера
Показать ещё 5 комментариев
Теги:
memory-management
realloc

3 ответа

3

Во-первых, realloc принимает 2 параметра. Сначала исходный указатель, а второй - новый. Вы пытаетесь передать размер в качестве исходного указателя, и код не должен компилироваться.

Во-вторых, обязательное напоминание: не оптимизируйте преждевременно. Если вы не измерили и не обнаружили, что выделение является узким местом, просто используйте std::vector.

  • 2
    Используйте std :: vector - хорошее предложение
1

Несколько вопросов, которые я заметил:

  • Realloc следует использовать, если вы хотите, чтобы старые значения оставались в памяти, если вы не беспокоились о старых значениях, как указано в одном из ваших комментариев, используйте только alloc.

  • Пожалуйста, проверьте размер уже выделенной памяти до выделения снова, если выделенной памяти недостаточно для новых данных, а затем выделите новую память.

Пожалуйста, обратитесь к образцу кода, который будет заботиться о вышеупомянутых проблемах:

int size = 2;   
int *a = (int*)std::alloc(size  * sizeof(int));

for(int i=0; i<N; ++i) 
{
   int m = calculate_enough_size();
   if(m > size)
   {
       size = m;
       std::free(a);
       a = (int*)std::alloc(size * sizeof(int));
   }
   // ...
}
std::free(a);

Кроме того, вы можете дополнительно оптимизировать распределение памяти, выделив некоторую дополнительную память, например:

size = m*2; //!

Чтобы лучше понять этот шаг, давайте предположим пример m = 8, тогда вы будете выделять память = 16, поэтому, когда теперь m изменяется на 10, 12 до 16, нет необходимости снова выделять память.

0

Если вы можете получить все размеры заранее, выделите самое большое, что вам нужно до цикла, а затем используйте столько, сколько необходимо.

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

Вы также можете оптимизировать свое решение путем перераспределения только тогда, когда требуется больший размер:

int size = 0;
for(int i = 0; i < N; ++i) 
{
    int new_size = calculate_enough_size();
    if ( new_size > size ){
        a = (int*)std::realloc(new_size * sizeof(int));
        size = new_size;
    }

    // ...
}

Таким образом вам понадобится меньше перераспределений (половина из них в рандомизированном случае).

  • 0
    Невозможно получить наибольшее значение m перед итерациями
  • 0
    msgstr "перераспределение только тогда, когда нужен больший размер". почему лучше перераспределять каждую итерацию?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню