0 / 0 / 0
Регистрация: 27.11.2014
Сообщений: 20
1

Освобождение динамической памяти

25.12.2018, 16:19. Показов 4307. Ответов 23
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день, объясните, пожалуйста, как правильно удалять выделенную динамическую память? Вот пример задачи, где массив произвольного размера может быть введен пользователем или взят из файла. Соответственно при вызове соответствующей функции выделяется память, массив вводится и сохраняется в выделенной памяти, чтобы его можно было вывести на экран. Если после этого снова вызывается функция ввода массива пользователем/из файла, то ранее выделенная память должна быть удалена, а новая выделиться, но компилятор мою интерпретацию такой логики не поддерживает.

Да и вообще в функции ввода из файла что-то не то. С клавиатуры можно вводить сколько угодно раз новый массив (правда освобождается ли при этом память, не знаю), а из файла в память ничего не сохраняется (срабатывает метка "массив пустой")

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>
#include <cstring>
#include <conio.h>
#include <fstream>
 
using namespace std;
 
void menu()
{
    cout << "1 - Ввести массив с клавиатуры"<<endl;
    cout << "2 - Ввести массив из файла" << endl;
    cout << "3 - Вывести массив на экран" << endl;
}
 
int* Input(int Arsize)
{
    int *arr = new int[Arsize];
 
    for (int i(0); i < Arsize; i++)//заполнение массива
    {
        cout << "Введите " << i+1 << "-ый элемент массива" << endl;
        cin >> arr[i];
    }
    return arr;
}
 
void Output(int * Arr, int arsize)
{
    for (int i(0); i < arsize; i++)//вывод массива
    {
        cout << *(Arr + i) << " ";
    }
    cout << endl;
}
 
 
int main()
{
 
    using namespace std;
    setlocale(LC_ALL, "Russian");
    int* massiv=NULL;
    int size;
    int temp;
    char choice;
 
    ofstream fout;
    ifstream fin;
 
    do
    {
        system("cls");
        menu();//вызов меню
 
        cin >> choice;
        switch (choice)
        {
        case '1': //ввод массива с клавиатуры
        {
            delete [] massiv;
            cout << "введите размерность массива" << endl;
            cin >> size;
            massiv = Input(size);
            break;
        }
 
        case '2':
        {
            delete [] massiv;
            fin.open("textfile.txt");
            if (!fin.is_open())
            {
                cout << "файл не найден";
                _getch();
                break;
            }
 
            int i = 0;
            while (!fin.eof()) //сосчитаем кол-во членов в массиве в текстовом файле
            {
                fin >> temp;
                i++;
                size=i;
            }
            //cout << size << endl; //вывод количества файлов в массиве
 
            int *massiv = new int[size];
            //massiv = NULL;
 
            fin.seekg(0);//перевод каретки в начало строки
 
            for (int i(0); i < size; i++)
            {
                fin >> massiv[i];
                cout << massiv[i] << " ";
            }
 
            _getch();
            break;
        }
 
        case '3': //вывод массива на экран
        {
            system("cls");
            if (massiv == NULL)
                cout << "массив пустой" << endl;
            else
                Output(massiv, size);
            _getch();
            break;
        }
 
    } while (choice !='q');
 
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.12.2018, 16:19
Ответы с готовыми решениями:

Освобождение динамической памяти
После первого вызова функции(при повторном) пишет ошибку. В функции sort один из элементов массива...

Освобождение динамической памяти
Здравствуйте! Была задача реализовать сложение длинных чисел с помощью стеков. Сам стек...

Освобождение динамической памяти в vs
Вообщем попался я тут, и так, код: //#define _CRT_SECURE_NO_WARNINGS добавить в vs #include...

Освобождение и выделение динамической памяти
Привет народ, такой вопрос: Допустим в main, указателю выделил память, всё разумеется нормально,...

23
Mental handicap
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
27.12.2018, 18:05 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Renji Посмотреть сообщение
"при попытке записи надо связать страницу виртуальной памяти с физической, но памяти нема"? Кто запросил связывание, того и по башке?
Если верно понял то в таком случае Windows предупредит пользователя об исчерпании памяти и автоматически отключит большинство дорогих программ. Типа винда же использует подкачку для «сохранения» программ, которые пока не используются, но все еще находятся в RAM.
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
27.12.2018, 18:27 22
Цитата Сообщение от Azazel-San Посмотреть сообщение
Если верно понял то в таком случае Windows предупредит пользователя об исчерпании памяти и автоматически отключит большинство дорогих программ.
По-моему, мы все же немного о разных вещах говорим.
1) Программа просит сто терабайт и получает ссылку на большой кусок виртуального адресного пространства. Реально в этом пространстве нет ни единого байта, но программа то об этом не знает.
2) Программа пытается сделать запись *myPointer=1234. Система перехватывает запись в никуда и пытается связать виртуальные адреса с физическими.
3) Система понимает что свободной физической памяти больше не осталось и связать виртуальный адрес не с чем. Что делать будем?

Даже если написать пользователю "память исчерпалась", у нас все еще остается программа пытающаяся сделать *myPointer=1234. Программа не ожидает что указатель ведет в никуда. А значит, ее нельзя предупредить "памяти нет, но вы держитесь". Остается только кого-то прибить. Или программу которая делает запись в никуда, или какой-то жадный процесс съевший память. Всех жалко, все были обмануты ОС которая под видом реальной памяти раздавала указатели в никуда.
1
3881 / 2479 / 418
Регистрация: 09.09.2017
Сообщений: 10,862
28.12.2018, 10:46 23
Цитата Сообщение от Renji Посмотреть сообщение
При попытке в эту память что-то записать приходит OOM Killer и убивает кого попало. И никак ты это не отследишь.
Но он не обязательно убьет именно "хапнувшую" программу.
И еще раз повторю: проверять надо не только выделение памяти, но и файлы, да и все прочие ресурсы, которые могут не выделиться.
Ах да, на счет памяти: мне вполне удавалось вызвать невозможность выделения памяти, и отловить эту ошибку. В лабораторных условиях, разумеется, исчерпать запасы современных машин не так просто.
Цитата Сообщение от Azazel-San Посмотреть сообщение
Renji, насколько я помню, если у нас не хватит физической памяти винда сделает файл подкачки
Это если файл подкачки настроен по умолчанию, на динамический размер. А если размер фиксирован, или файл подкачки отключен, или просто место закончилось?
Цитата Сообщение от Azazel-San Посмотреть сообщение
Типа винда же использует подкачку для «сохранения» программ, которые пока не используются, но все еще находятся в RAM.
Ни кэширование программ и дисков, ни подкачка не являются специфичными для винды. Все так делают. Речь-то о том, что делать когда оперативная память вот совсем закончилась, и все резервы исчерпаны.
Цитата Сообщение от Renji Посмотреть сообщение
Программа не ожидает что указатель ведет в никуда. А значит, ее нельзя предупредить "памяти нет, но вы держитесь". Остается только кого-то прибить.
Теоретически, ее можно "заморозить". В принципе, это произойдет в любом случае, по крайней мере до того момента пока ОС не разберется с соответствием адресов или убийством лишних.
1
Mental handicap
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
28.12.2018, 14:23 24
Цитата Сообщение от Renji Посмотреть сообщение
Система понимает что свободной физической памяти больше не осталось и связать виртуальный адрес не с чем. Что делать будем?
Произойдет то же, что и если бы процес запросил доступ к странице которая сейчас в свопе: page fault. А сам процес был бы в ожидании готовности пока система не даст зеленый свет.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
все резервы исчерпаны.
Помню у меня на виндовс ХР еще вроде, при такой ситуации были лаги на уровне полного зависания системы и/или рандомные убийства процессов, потом повторять не пытался, вполне вероятно начнется магия Теперь самому стал интересен этот вопрос, я еще не очень опытен в этом вопросе, но вообще как я помню винда латентна в таких вопросах и дает "каменное" обещание что такого не произойдет (но это все на уровне условностей, офк).
0
28.12.2018, 14:23
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.12.2018, 14:23
Помогаю со студенческими работами здесь

Выделение и освобождение динамической памяти в функциях
Каким образом происходит выделение и очистка динамической памяти для массивов (в частности) в...

Освобождение динамической памяти из-под прямоугольной матрицы
Добрый вечер! При попытке очищения памяти после завершения работы программы с прямоугольной...

Резервирование памяти/освобождение памяти для трехмерного массива
Необходимо создать трехмерный массив (A), в котором элементы вдоль направления Z выли бы выровнены...

Освобождение памяти в C++
Добрый день! В моей программе в функции выделяется память (new char) под символьный массив,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
24
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru