Я пытаюсь использовать realloc () в приложении Windows. Я выделяю большой блок памяти, а затем использую realloc (), чтобы уменьшить его позже, когда я узнаю правильный размер.
Я обнаружил, что, хотя realloc () работает правильно (память в диспетчере задач отражает то, что вы ожидаете), в конечном итоге у приложения заканчивается память. Насколько я могу судить, это как если бы relloc () освобождает память, но не освобождает виртуальное адресное пространство, связанное с памятью. В результате malloc () в конечном итоге завершится ошибкой.
Вот небольшое консольное приложение, демонстрирующее проблему:
int _tmain(int argc, _TCHAR* argv[])
{
static const DWORD dwAllocSize = (50 * 1024 * 1024);
static const DWORD dwReallocSize = 10240;
static const DWORD dwMaxIterations = 200;
BYTE* arpMemory[dwMaxIterations];
memset( arpMemory, 0, sizeof(arpMemory) );
for( DWORD i = 0; i < dwMaxIterations; i++ )
{
arpMemory[i] = (BYTE*) malloc( dwAllocSize );
if( !arpMemory[i] )
{
printf("OUT OF MEMORY after %d iterations!\n", i);
return -1;
}
BYTE* pRealloc = (BYTE*) realloc( arpMemory[i], dwReallocSize );
if( !pRealloc )
{
printf("Realloc FAILED after %d iterations!\n", i);
return -1;
}
else if( pRealloc != arpMemory[i] )
{
printf("Warning: Pointer changed: 0x%08X -> 0x%08X\n", arpMemory[i], pRealloc);
arpMemory[i] = pRealloc;
}
}
printf("Success!\n");
for( int i = 0; i < dwMaxIterations; i++ )
free( arpMemory[i] );
return 0;
}
Приложение постоянно выделяет 50 МБ памяти, а затем сразу же изменяет ее размер до 10 КБ. Если вы запустите его, то обнаружите, что он завершается с ошибкой НЕТ ПАМЯТИ после всего лишь 38 итераций. Это соответствует 2 ГБ изначально выделенной памяти - это предел адресного пространства для приложений Windows.
Интересно, что если вы посмотрите в диспетчере задач, вы увидите, что приложение почти не занимает памяти. Однако malloc () не работает. Это то, что заставляет меня думать, что виртуальное адресное пространство исчерпывается.
(Еще один эксперимент, который нужно попробовать, - закомментировать перераспределение, чтобы память не освобождалась и не перераспределялась. Приложение терпит неудачу точно в том же месте: после 38 итераций. Единственная разница в том, что на этот раз Диспетчер задач отражает все используемые 2 ГБ.)
И последнее: это же приложение работает под Linux. Таким образом, эта проблема realloc () относится только к Windows.
Есть предположения?