Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 17.07.2015
Сообщений: 11
1

Не получается освободить память динамического двумерного массива

13.09.2015, 11:43. Показов 1627. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пишу в Visual Studio 2015 Community

Объявляю двумерный динамический массив так:
C++
1
2
3
4
5
int **mas = new int* [sizeY];
for (int i = 0;i < sizeY;i++) 
{
    mas[i] = new int[sizeX];
}
После завершения работы освобождаю память так:
C++
1
2
3
for (int i = 0;i < sizeY;i++)
    delete [] mas[i];
delete[] mas;
В результате на экране вижу эту прекрасную картинку прикрепленную ниже. Эта ошибка происходит всегда именно при значении счетчика i когда он доходит до 2. Подскажите пожалуйста как избавиться от этой ошибки.
Миниатюры
Не получается освободить память динамического двумерного массива  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.09.2015, 11:43
Ответы с готовыми решениями:

Удаление строки из двумерного динамического массива
Написал код который добавляет в массив структур новый элемент. Но не получается написать функцию...

Освободить память от двумерного динамического массива
помогите, пожалуйста, разобраться с очисткой динамического массива.Спасибо....

Как правильно освободить память двумерного массива
Память для test выделена так: char **test; test = (char **)calloc(n, sizeof(char *)); Чтобы...

Не получается освободить память
Здравствуйте, такая загвоздка, начал изучать указатели и создание динамических массивов, проблема в...

10
0 / 0 / 0
Регистрация: 17.07.2015
Сообщений: 11
13.09.2015, 11:53  [ТС] 2
Не правильно написал в теме...

Объявляю динамический массив так (иначе пишет что массив неиницализирован)
C++
1
2
int **mas = new int*[0];
    mas[0] = new int[0];
Затем передаю его в функцию где задаю размерность
C++
1
2
3
4
5
int **mas = new int* [sizeY];
for (int i = 0;i < sizeY;i++) 
{
    mas[i] = new int[sizeX];
}
А в завершении уже потом освобождаю память
C++
1
2
3
for (int i = 0;i < sizeY;i++)
    delete [] mas[i];
delete[] mas;
0
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,305
14.09.2015, 02:22 3
Цитата Сообщение от Ullr Посмотреть сообщение
Объявляю динамический массив так
Это неправильно. Такого быть не должно.
Больше без полного кода нельзя сказать.
1
0 / 0 / 0
Регистрация: 17.07.2015
Сообщений: 11
14.09.2015, 11:12  [ТС] 4
Цитата Сообщение от DrOffset Посмотреть сообщение
Это неправильно. Такого быть не должно.
Больше без полного кода нельзя сказать.
Увы код уже сильно изменил.
После нескольких экспериментов пришел к выводу что освободить память динамического массива можно только в той функции в которой она была выделена (хотя в интернете об этом не нашел упоминаний), переместил освобождение памяти из отдельной функции в конец функции в которой она была выделена и ошибка исчезла.

P.s. хотел вынести освобождение в отдельную функцию потому что данные из массива понадобятся позже если пользователь выберет другой пункт меню, по этому пришлось использовать файлы для хранения данных.
0
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,305
14.09.2015, 14:14 5
Цитата Сообщение от Ullr Посмотреть сообщение
После нескольких экспериментов пришел к выводу что освободить память динамического массива можно только в той функции в которой она была выделена
И это также неверный вывод.
Если все-таки есть желание, чтобы научили и подсказали, то лучше выложить проблемный код
1
0 / 0 / 0
Регистрация: 17.07.2015
Сообщений: 11
14.09.2015, 18:38  [ТС] 6
Цитата Сообщение от DrOffset Посмотреть сообщение
И это также неверный вывод.
Если все-таки есть желание, чтобы научили и подсказали, то лучше выложить проблемный код
Буду очень благодарен если подскажите как исправить проблему
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <clocale>
#include <stdlib.h>
#include <ctime>
#include <fstream>
#include <io.h>
 
using namespace std;
 
int menu();
bool**  read(bool**, int, int);
bool** hand(bool**, int, int);
bool** random(bool**, int, int);
int writRez();
int analysis();
bool** deleteMas(bool**, int, int);
 
int main() {
    setlocale((LC_ALL), "Russiun");
    setlocale((LC_ALL), "rus");
    menu();
    bool **mass = new bool*[0];
    char p;
    int n = 0, m = 0;
    do
    {
        p = _getch();
        switch (p)
        {
        case 'a':
        case'A':
        {
            if (n > 0) {
                deleteMas(mass, n, m);
            }
            system("cls");
            menu();
            printf("A\nВведите количество строк (число больше 0): ");
 
            ///////////////////////////
            do
            {
                scanf_s("%d", &n);
                while (scanf_s("%c", &p))               // анализ нажатых клавиш после завершения ввода числа
                {                                       // 
                    if (p == '\n')                      //
                    {                                   //
                        break;                          //
                    }                                   //
                    else                                //
                    {                                   //
                        if (p != ' ')                   //
                        {                               //
                            n = 0;                      //
                        }                               //
                    }                                   //
                }
                if (n <= 0) printf("Введено недопустимое значение, повторите ввод: ");
            } while (n <= 0);
            //////////////////////////
            printf("Введите количество столбцов (число больше 0): ");
            do
            {
                scanf_s("%d", &m);
                while (scanf_s("%c", &p))               // анализ нажатых клавиш после завершения ввода числа
                {                                       //
                    if (p == '\n')                      //
                    {                                   //
                        break;                          //
                    }                                   //
                    else                                //
                    {                                   //
                        if (p != ' ')                   //
                        {                               //
                            m = 0;                      //
                        }                               //
                    }                                   //
                }
                if (m <= 0) printf("Введено недопустимое значение, повторите ввод: ");
            } while (m <= 0);
            ////////////////////
            read(mass,n, m);
            system("cls");
            menu();
            printf("A\nМассив успешно заполнен\n");
            printf("\nДля выбора пункта меню введите соответствующую букву: ");
            remove("analysis.txt");
            break;
        }
        case'b':
        case'B':
        {
            system("cls");
            menu();
            printf("B\n");
            analysis();
            break;
        }
        case'c':
        case'C':
        {
            writRez();
            break;
        }
        }
    } while (p != 'D' && p != 'd'&&p != 'В'&&p != 'в');
    return 0;
}
//
//
//
int menu() {
    printf("\t\t\tПрограмма для расчета количества проданных билетов на сеанс\n\t\t\t\t и количества билетов в заданном ряду\n");
    printf("\tA. Ввести данные о проданных билетах\n\tB. Обработать данные\n\tC. Вывести данные\n\tD. Выход\n\n");
    printf("Для выбора пункта меню введите соответствующую букву: ");
    return 0;
}
//
//
//
bool** read(bool** mass, int sizeY, int sizeX) {
    mass = new bool*[sizeY];
    for (int i = 0;i < sizeY;i++)
    {
        mass[i] = new bool[sizeX];
    }
    char p;
    printf("Ручной ввод массива (Y/N): ");
    do {
        p = _getch();
        switch (p) {
        case 'y':
        case 'Y': {
            printf("Y\n");
            printf("\n");
            mass = hand(mass, sizeY, sizeX);
            break;
        }
        case 'n':
        case 'N': {
            printf("N\n");
            mass = random(mass, sizeY, sizeX);
            break;
        }
        }
    } while (p != 'Y' && p != 'y' && p != 'n' && p != 'N');
    return mass;
}
//
//
//
bool** hand(bool** mas, int sizeY, int sizeX)
{
    ofstream out;
    out.open("data.txt");
    out << sizeY << " " << sizeX << endl;
    char p;
    for (int i = 0;i < sizeY;i++)
    {
        printf("Введите данные о %d-ом ряде: \n", (i + 1));
        for (int j = 0;j < sizeX;j++) {
            printf("_");
        }
        printf("\r");
        for (int j = 0;j < sizeX;j++)
        {
            do {
                p = _getch();
            } while (p != '1'&&p != '0');
            if (p == '1')
            {
                mas[i][j] = 1;
                out << "1 ";
            }
            else
            {
                out << "0 ";
                mas[i][j] = 0;
            }
            printf("%c", p);
        }
        out << endl;
        printf("\n");
    }
    out.close();
    return mas;
}
//
//
//
bool** random(bool** mas, int sizeY, int sizeX)
{
    srand(time(NULL));
    ofstream out;
    out.open("data.txt");
    out << sizeY << " " << sizeX << endl;
    for (int i = 0;i < sizeY;i++)
    {
        for (int j = 0;j < sizeX;j++)
        {
            mas[i][j] = rand() % 2;
            out << mas[i][j] << " ";
        }
        out << endl;
    }
    out.close();
    return mas;
}
//
//
//
int analysis()
{
    if (!_access("data.txt", 0)) {
        ifstream in;
        in.open("data.txt");
        ofstream out;
        out.open("analysis.txt");
        int sizeX, sizeY, bought, series = 0;
        bool x;
        in >> sizeY >> sizeX;
        out << sizeY*sizeX << endl << sizeY << " " << sizeX << endl;
        for (int i = 0;i < sizeY;i++)
        {
            bought = 0;
            for (int j = 0;j < sizeX;j++)
            {
                in >> x;
                bought += (int)x;
                series += (int)x;
            }
            out << bought << endl;
        }
        out << series;
        in.close();
        out.close();
        printf("Данные успешно проанализированы\n");
    }
    else
    {
        printf("Данные не введены\n");
    }
    printf("\nДля выбора пункта меню введите соответствующую букву: ");
    return 0;
}
//
//
//
int writRez()
{
    if (!_access("analysis.txt", 0)) {
        ifstream in;
        in.open("analysis.txt");
        int sizeY, sizeX, mest, series;
        in >> mest >> sizeY >> sizeX;
        int* mas = new int[sizeY];
        for (int i = 0;i < sizeY;i++)
        {
            in >> mas[i];
        }
        in >> series;
        int n = 0;
        char p;
        do {
            system("cls");
            menu();
            printf("C\n");
            printf("\tВсего мест: %d\n", mest);
            printf("\tВсего продано билетов: %d\n", series);
            printf("\tВсего рядов: %d\n", sizeY);
            if (n > 0) {
                printf("Введите номер ряда для подсчета занятых мест в этом ряду (для завершения введите 0): %d", n);
                printf("\nВ %d-ом ряду продано: %d\n", n, mas[n - 1]);
                printf("В %d-ом ряду осталось: %d\n", n, sizeX - mas[n - 1]);
            }
            printf("Введите номер ряда для подсчета занятых мест в этом ряду (для завершения введите 0): ");
            do
            {
                scanf_s("%d", &n);
                while (scanf_s("%c", &p))               // анализ нажатых клавиш после завершения ввода числа
                {                                       //
                    if (p == '\n')                      //
                    {                                   //
                        break;                          //
                    }                                   //
                    else                                //
                    {                                   //
                        if (p != ' ')                   //
                        {                               //
                            n = -1;                     //
                        }                               //
                    }                                   //
                }
                if (n < 0 || n>sizeY)
                {
                    printf("Введено недопустимое значение, повторите ввод: ");
                }
            } while (n < 0 || n>sizeY);
        } while (n != 0);
        in.close();
        system("cls");
        menu();
    }
    else
    {
        system("cls");
        menu();
        printf("C\n");
        printf("Данные не проанализированы\n");
        printf("\nДля выбора пункта меню введите соответствующую букву: ");
    }
    return 0;
}
 
bool** deleteMas(bool** mas, int sizeY, int sizeX) {
    for (int i = 0;i < sizeY;i++)
        delete[] mas[i];
    delete[] mas;
    return mas;
}
Добавлено через 8 минут
Изначально задумывалось что массив будет один для всех функций но из за того что не получилось так сделать сделал через файлы, сейчас не стал все возвращать обратно, а просто вернул то как у меня было удаление массива и его объявление.
0
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,305
14.09.2015, 18:42 7
Лучший ответ Сообщение было отмечено tezaurismosis как решение

Решение

Ullr, давай начнем вот с этих исправлений:
Строка 14:
C++
1
bool**  read(bool** &, int, int); // было bool**  read(bool**, int, int);
Строка 24:
C++
1
    bool **mass = 0; // было bool **mass = new bool*[0];
Строка 123:
C++
1
bool** read(bool** & mass, int sizeY, int sizeX) // было bool** read(bool** mass, int sizeY, int sizeX)
Проверяй.
1
0 / 0 / 0
Регистрация: 17.07.2015
Сообщений: 11
14.09.2015, 18:47  [ТС] 8
Теперь ошибку не выдает

То есть надо было отправлять массив как бы "не копию", а именно "оригинал" (я про знак & перед названием массива как параметр в функции) ?
0
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,305
14.09.2015, 19:00 9
Цитата Сообщение от Ullr Посмотреть сообщение
То есть надо было отправлять массив как бы "не копию", а именно "оригинал" (я про знак & перед названием массива как параметр в функции) ?
Ну конечно. Только не массив, а указатель. Здесь важно, чтобы указатель mass в main имел то самое значение, что мы получили в функции read. До этого, у тебя оставалось прежнее значение, а вот удалялся массив уже как будто бы значение новое.
Если по указателю не находятся те данные, которые ждет delete, то мы как раз будем наблюдать спецэффекты, наподобие твоих.
1
0 / 0 / 0
Регистрация: 17.07.2015
Сообщений: 11
14.09.2015, 19:04  [ТС] 10
Спасибо огромное. Не знал что так можно, теперь буду знать
0
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,305
14.09.2015, 19:08 11
Цитата Сообщение от Ullr Посмотреть сообщение
Не знал что так можно, теперь буду знать
Можно было бы сделать более классически. Функция read возвращала бы указатель на выделенную память. А в функции main просто было бы присвоение.
C++
1
mass = read(n, m);
Получилось бы тоже самое, но менее вычурно и более привычно.
1
14.09.2015, 19:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.09.2015, 19:08
Помогаю со студенческими работами здесь

Не получается адрес динамического двумерного массива передать, как аргумент функции
/* Лабораторная работа №3 Во всех вариантах необходимо написать три функции, которые будут...

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

Как освободить старые ImageVew чтобы освободить память
Привет всем Я новичок поэтому прошу сильно не пинать. В общем мое первое приложение типа интернет...

Можно ли освободить память от последней ячейки массива и как?
Пробую с помощью delete, не выходит. Выдаёт ошибку &quot;wntdll.pdb не загружен&quot;. Почему так? ...


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

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