Мне нужно выделить пространство для временного массива один раз за итерацию. Я пытаюсь использовать 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
Предотвращает ли это избыточное выделение памяти?
Во-первых, realloc
принимает 2 параметра. Сначала исходный указатель, а второй - новый. Вы пытаетесь передать размер в качестве исходного указателя, и код не должен компилироваться.
Во-вторых, обязательное напоминание: не оптимизируйте преждевременно. Если вы не измерили и не обнаружили, что выделение является узким местом, просто используйте std::vector
.
Несколько вопросов, которые я заметил:
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, нет необходимости снова выделять память.
Если вы можете получить все размеры заранее, выделите самое большое, что вам нужно до цикла, а затем используйте столько, сколько необходимо.
Если, с другой стороны, вы не можете этого сделать, то перераспределение является хорошим решением, я думаю.
Вы также можете оптимизировать свое решение путем перераспределения только тогда, когда требуется больший размер:
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;
}
// ...
}
Таким образом вам понадобится меньше перераспределений (половина из них в рандомизированном случае).