С памятью свободной путаницы - PullRequest
2 голосов
/ 12 ноября 2011

У меня короткий вопрос о моем коде. Я создал две ситуации или примеры для тестирования.

пример 1:

char *arr[1000000];
int i = 0;
for (; i < 1000000; i++){
    char *c = (char *) calloc(1, sizeof(char) * 10);
    free(c);
}

пример 2:

char *arr[1000000];
int i = 0;
for (; i < 1000000; i++){
    char *c = (char *) calloc(1, sizeof(char) * 10);
    arr[i] = c;
    free(arr[i]);
    arr[i] = NULL;
}

Различия в примерах: помещение массива перед освобождением памяти.

Когда я запускаю пример 1, он освобождает всю память. Когда я запускаю пример 2, он не освобождает всю память. Я искал и смотрел, но не мог понять.

Почему результат примера 2 отличается от примера 1?

Мой здравый смысл говорит мне, что примеры 1 и 2 должны приводить к одному и тому же результату, но на практике это не так. Я использую linux top для проверки использования памяти.

Ответы [ 3 ]

4 голосов
/ 12 ноября 2011

Результат одинаков.Я не уверен, почему вы думаете, что есть различия.

3 голосов
/ 12 ноября 2011

Это вызвано пейджингом по требованию. У процесса есть адресное пространство для массива (то есть: для него существуют записи в виде таблицы), но к нему еще не подключена память (пока). Цикл присваивает (в конечном итоге) всем страницам памяти, принадлежащим массиву [], поэтому в конце цикла все страницы были «повреждены».

В качестве подтверждения концепции вы можете заменить цикл на:

for (; i < 1000000; i++){
    arr[i] = "hello, world!";
}

И результат, вероятно, будет (почти) таким же, как во фрагменте # 2

3 голосов
/ 12 ноября 2011

Оба одинаковы.

Поскольку вы используете top для чтения памяти, разницу можно объяснить оптимизацией компилятора. Например, массив в примере один может быть полностью оптимизирован.

Для проверки проблем с памятью вы должны использовать valgrind или аналогичный инструмент.

...