Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Wanee
54 / 54 / 13
Регистрация: 02.02.2011
Сообщений: 434
#1

Проблемы с памятью - C++

15.04.2013, 09:55. Просмотров 460. Ответов 18
Метки нет (Все метки)

Программа создает династическую двумерную матрицу. Не могу найти где происходит утечка памяти. Если несколько раз вводить большие размеры матрицы, то не происходит полная очистка памяти и программа просто закрывается. Помогите найти утечку и очищать память корректно.

Often.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef _OFTEN_H_
#define _OFTEN_H_
 
bool Ioresult(std::istream &stream); //Функция проверки правильности ввода c клавиатуры;
bool Ioresult(std::ifstream &stream); //Функция проверки правильности ввода из файла;
 
void Сlean(long **&meas, long size_y, long size_x); //Функция очищает выделенную память под матрицу;
void Init(long **&meas, long size_y, long size_x); //Функция выделяет память для матрицы C размеными Size_y на Size_x;
long Sing(long **&meas, long size_y, long size_x); //Функция возвращает строку с максимальной суммой модулей элементов;
void Save(long **&meas, long size_y, long size_x, std::ofstream &stream, char *&name); //Функция сохранения матрицы в файл;
void Open(long **&meas, long &size_y, long &size_x, std::ifstream &stream, char *&name); //Функция для заполнения из файла;
 
#endif
Often.cpp
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
#include <iostream> //istream;
#include <fstream> //ifstream, ofstream;
#include <stdlib.h> //abs(), system();
 
#include "Often.h"
 
bool Ioresult(std::ifstream &stream)
{   
    if(stream.fail())
    {
        stream.clear(); stream.sync();
        return true;
    }
    return false;
}
 
bool Ioresult(std::istream &stream)
{
    if(stream.rdbuf()->in_avail() != 1)
    {
        stream.clear(); stream.sync();
        return true;
    }
    stream.sync();
    return false;
}
 
void Сlean(long **&meas, long size_y, long size_x)
{
    if(!meas) throw 1; //Ошибка, память не выделена;
    if(size_y < 1 || size_x < 1) throw 3; //Ошибка, неправильные размеры;;
    for(long j = 0; j < size_y; j++) delete [] meas[j];
    delete [] meas;
    meas = 0;
}
 
void Init(long **&meas, long size_y, long size_x)
{
    if(meas) throw 2; //Ошибка, память уже выделена;
    if(size_y < 1 || size_x < 1) throw 3; //Ошибка, неправильные размеры;
    meas = new long*[size_y];
    for(long j = 0; j < size_y; j++) meas[j] = new long[size_x];
    for(long j = 0; j < size_y; j++)
        for(long i = 0; i < size_x; i++) meas[j][i] = 0;
}
 
long Sing(long **&meas, long size_y, long size_x)
{
    if(!meas) throw 1; //Ошибка, память не выделена;
    if(size_y < 1 || size_x < 1) throw 3; //Ошибка, неправильные размеры;
    for(long j = 0; j < size_y; j++) if(!meas[j]) throw 5; //Ошибка, память выделена не под всю матрицу;
    long Max = 0, Index = -1, Sum;
    bool Soot;
    for(int j = 0; j < size_y; j++)
    {
        Sum = 0;
        Soot = true;
        for(long i = 0; i < size_x; i++)
        {
            Sum = abs(meas[j][i]);
            if(!(meas[j][i] % 2)) Soot = false;
        }
        if(Soot && Max < Sum)
        {
            Max = Sum;
            Index = j;
        }
    }
    if(Index == -1) throw 6; //Ошибка, не найдено не одной строки удовлетворяющих требованиям;
    return Index;
}
 
void Save(long **&meas, long size_y, long size_x, std::ofstream &stream, char *&name)
{
    if(!meas) throw 1; //Ошибка, память не выделена;
    if(size_y < 1 || size_x < 1) throw 3; //Ошибка, неправильные размеры;
    for(long j = 0; j < size_y; j++) if(!meas[j]) throw 5; //Ошибка, память выделена не под всю матрицу;
    stream.open(name, std::ios_base::out);
    if (!stream.is_open()) throw 7; //Ошибка, не удалось открыть файл для записи;
    stream << size_y << ' ' << size_x << '\n';
    for(long j = 0; j < size_y; j++)
    {
        for(long i = 0; i < size_x; i++)
        {
            stream << meas[j][i];
            if(i < size_x - 1) stream << ' ';
        }
        if(j < size_y - 1) stream << '\n';
    }
    stream.close();
}
 
void Open(long **&meas, long &size_y, long &size_x, std::ifstream &stream, char *&name)
{
    if(meas) throw 2; //Ошибка, память уже выделена;
    stream.open(name, std::ios_base::in);
    if (!stream.is_open()) throw 8; //Ошибка, не удалось открыть файл для чтения;
    if(stream.eof())
    {
        stream.close();
        throw 9; //Ошибка, файл пуст;
    }
    stream >> size_y;
    if(Ioresult(stream))
    {
        stream.close();
        throw 10; //Ошибка, не удалось считать содерживое файла;
    }
    if(stream.eof())
    {
        stream.close();
        throw 11; //Ошибка, не хватает данных в файле;
    }
    stream >> size_x;
    if(Ioresult(stream))
    {
        stream.close();
        throw 10; //Ошибка, не удалось считать содерживое файла;
    }
    Init(meas, size_y, size_x);
    long j = 0, i = 0;
    while(!stream.eof() && j != size_y)
    {
        stream >> meas[j][i];
        if(Ioresult(stream))
        {
            Сlean(meas, size_y, size_x);
            stream.close();
            throw 10; //Ошибка, не удалось считать содерживое файла;
        }
        i++;
        if(i == size_x)
        {
            j++;
            i = 0;
        }
    }
    if(j != size_y)
    {
        Сlean(meas, size_y, size_x);
        stream.close();
        throw 11; //Ошибка, не хватает данных в файле;
    }
    if(stream.rdbuf()->in_avail())
    {
        Сlean(meas, size_y, size_x);
        stream.close();
        throw 12; //Ошибка, в файле содержаться лишний данные;
    }
    stream.close();
}
Main.cpp
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
#include <iostream> //istream;
#include <fstream> //ifstream, ofstream;
#include <stdlib.h> //abs(), system();
#include <conio.h> //getch();
#include <stdio.h> //gets();
#include <time.h> //time();
#include <new> //bad_alloc
 
#include "Often.h"
 
using namespace std;
 
void PrintR(int x)
{
    switch(x)
    {
    case 1:
        cout << "Ошибка, память не выделена. ";
        break;
    case 2:
        cout << "Ошибка, память уже выделена. ";
        break;
    case 3:
        cout << "Ошибка, неправильные размеры. ";
        break;
    case 5:
        cout << "Ошибка, память выделена не под всю матрицу. ";
        break;
    case 6:
        cout << "Ошибка, не найдено не одной строки удовлетворяющих требованиям. ";
        break;
    case 7:
        cout << "Ошибка, не удалось открыть файл для записи. ";
        break;
    case 8:
        cout << "Ошибка, не удалось открыть файл для чтения. ";
        break;
    case 9:
        cout << "Ошибка, файл пуст. ";
        break;
    case 10:
        cout << "Ошибка, не удалось считать содерживое файла. ";
        break;
    case 11:
        cout << "Ошибка, не хватает данных в файле. ";
        break;
    case 12:
        cout << "Ошибка, в файле содержаться лишний данные. ";
        break;
    default:
        cout << "Неизвестная ошибка. ";
    }
}
 
void main(int argc, char *argv[])
{
    srand(time(NULL)); //Для генераций случайных чисел
    setlocale(LC_ALL, "Russian");   
 
    long **meas = 0;
    long size_y, size_x;
    char *name = new char[261];
    ifstream in;
    ofstream out;
 
    if(argc == 2)
    {
        try
        {
            Open(meas, size_y, size_x, in, argv[1]);
            system("cls");
            cout << "Матрица успешно считана из файл. ";
            system("pause");
        }
        catch(int x)
        {
            system("cls");
            PrintR(x);
            system("pause");
        }
        catch(bad_alloc)
        {
            if(!meas) Сlean(meas, size_y, size_x);
            system("cls");
            cout << "Нехватило памяти. ";
            system("pause");
        }
    }
    
    bool ext = true;
    char ch;
    int item = 1;
 
    do{
        system("cls");
        switch(item){
        case 1:
            cout << "1.Создать.\n";
            cout << "2.Просмотреть.\n";
            cout << "3.Обработать.\n";
            cout << "4.Сохранить в файл.\n";
            cout << "5.Выход.\n";
            break;
        case 2:
            cout << "1.С клавиатуры.\n";
            cout << "2.Случайным образом.\n";
            cout << "3.Заполнить из файла.\n";
            cout << "4.Назад.\n";
            break;
        }
 
        ch = getch();
 
        try
        {
            switch(item)
            {
            case 1:
                switch(ch)
                {
                case '1':
                    item = 2;
                    break;
                case '2':
                    if(!meas) throw 1; //Ошибка, память не выделена;
                    if(size_y < 1 || size_x < 1) throw 3; //Ошибка, неправильные размеры;
                    for(long j = 0; j < size_y; j++) if(!meas[j]) throw 5; //Ошибка, память выделена не под всю матрицу;
                    system("cls");
                    cout << "Элементы матрица:\n";
                    for(long j = 0; j < size_y; j++)
                    {
                        for(long i = 0; i < size_x; i++)
                        {
                            cout << meas[j][i];
                            if(i < size_x - 1) cout << ' ';
                        }
                        if(j < size_y - 1) cout << '\n';
                    }
                    system("pause");
                    break;
                case '3':
                    if(!meas) throw 1; //Ошибка, память не выделена;
                    if(size_y < 1 || size_x < 1) throw 3; //Ошибка, неправильные размеры;
                    for(long j = 0; j < size_y; j++) if(!meas[j]) throw 5; //Ошибка, память выделена не под всю матрицу;
                    system("cls");
                    cout << "Номер строки: " << Sing(meas, size_y, size_x) << '\n';
                    system("pause");
                    break;
                case '4':
                    if(!meas) throw 1; //Ошибка, память не выделена;
                    if(size_y < 1 || size_x < 1) throw 3; //Ошибка, неправильные размеры;
                    for(long j = 0; j < size_y; j++) if(!meas[j]) throw 5; //Ошибка, память выделена не под всю матрицу;
                    system("cls");
                    cout << "Введите имя файла: ";
                    gets(name);
                    Save(meas, size_y, size_x, out, name);
                    system("cls");
                    cout << "Матрица успешно записана в файл. ";
                    system("pause");
                    break;
                case '5':
                    ext = false;
                    if(meas) Сlean(meas, size_y, size_x);
                    delete []name;
                    break;
                }
                break;
            case 2:
                switch(ch)
                {
                case '1':
                    if(meas) Сlean(meas, size_y, size_x);
                    do{
                        system("cls");
                        cout << "Введите количество строк матрицы: ";
                        cin >> size_y;
                    }while(Ioresult(cin));
                    do{
                        system("cls");
                        cout << "Введите количество столбцов матрицы: ";
                        cin >> size_x;
                    }while(Ioresult(cin));
                    Init(meas, size_y, size_x);
                    for(long j = 0; j < size_y; j++)
                        for(long i = 0; i < size_x; i++)
                            do{
                                system("cls");
                                cout << "Введите C[" << j << "][" << i << "]: ";
                                cin >> meas[j][i];
                            }while(Ioresult(cin));
                    system("cls");
                    cout << "Матрица успешно создана. ";
                    system("pause");
                    break;
                case '2':
                    if(meas) Сlean(meas, size_y, size_x);
                    do{
                        system("cls");
                        cout << "Введите количество строк матрицы: ";
                        cin >> size_y;
                    }while(Ioresult(cin));
                    do{
                        system("cls");
                        cout << "Введите количество столбцов матрицы: ";
                        cin >> size_x;
                    }while(Ioresult(cin));
                    Init(meas, size_y, size_x);
                    for(long j = 0; j < size_y; j++)
                        for(long i = 0; i < size_x; i++) meas[j][i] = rand();
                    system("cls");
                    cout << "Матрица успешно создана. ";
                    system("pause");
                    break;
                case '3':
                    if(meas) Сlean(meas, size_y, size_x);
                    system("cls");
                    cout << "Введите имя файла: ";
                    gets(name);
                    Open(meas, size_y, size_x, in, name);
                    system("cls");
                    cout << "Матрица успешно считана из файл. ";
                    system("pause");
                    break;
                case '4':
                    item = 1;
                    break;
                }
                break;
            }
 
        }
        catch(int x)
        {
            system("cls");
            PrintR(x);
            system("pause");
        }
        catch(bad_alloc)
        {
            if(!meas) Сlean(meas, size_y, size_x);
            system("cls");
            cout << "Нехватило памяти. ";
            system("pause");
        }
    }while(ext);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.04.2013, 09:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Проблемы с памятью (C++):

проблемы с памятью.... - C++
с алгоритмом вроде все нормально но вот происходит такая вещи при определенном действии выдается сообщение которое на скриншоте.... потом...

Сортировки. Проблемы с памятью - C++
#include &lt;time.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;conio.h&gt; unsigned int count; struct stack {int left; ...

std:bad_alloc Проблемы с памятью - C++
Здравствуйте, проблема такая. Написал программу итерационного метода. Далее эту программу, поместил в функцию. И вызываю очень часто...

Работа с памятью - C++
Форумчане, доброго времени суток. Заранее извиняюсь за нубские вопросы, но должен разобраться в теме. Суть такова: написал class...

работа с памятью - C++
a) Статическая память. Двумерный массив. Дан массив целых чисел. В массиве есть отрицательные числа. Определить координаты левого нижнего...

Работа с памятью - C++
Всем доброго времени суток. Почитав данный форум и проч. пришёл к выводу, что мой проект на C# нереален в виду бестолковой работы с...

18
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
15.04.2013, 10:58 #2
Wanee, ознакомьтесь в с концепцией RAII для исключения утечек памяти. И не используйте исключения типа int. Это плохой тон. Заведите специальный класс.
Искать утечки в Вашем коде слишком утомительно в силу ужасной кривизны. Проще переписать.
0
Wanee
54 / 54 / 13
Регистрация: 02.02.2011
Сообщений: 434
15.04.2013, 13:52  [ТС] #3
Tulosba, да логичней использовать свой тип, но по заданию я нельзя пользоваться классами, так что пришлось использовать int.
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
15.04.2013, 13:55 #4
Цитата Сообщение от Wanee Посмотреть сообщение
но по заданию я нельзя пользоваться классами
Что за садистское задание? Не пользоваться классами в программе на С++.
0
stima
487 / 339 / 39
Регистрация: 22.03.2011
Сообщений: 1,082
Завершенные тесты: 2
15.04.2013, 14:19 #5
thinking

Добавлено через 21 минуту
Код попахивает, но ...
1. Кто сказал что у Вас лик?
2. матрицу каких размеров Вы аллоцируете?
0
Wanee
54 / 54 / 13
Регистрация: 02.02.2011
Сообщений: 434
15.04.2013, 14:22  [ТС] #6
Tulosba, одно из требований "8. Программы реализуются на языке С++ БЕЗ использования классов."
0
stima
487 / 339 / 39
Регистрация: 22.03.2011
Сообщений: 1,082
Завершенные тесты: 2
15.04.2013, 14:24 #7
Используйте функции это раз. Можно енумчик?, нет -> дефайны, это два. Три у вас ошибка на bad alloc !means и Вы не переходите в режим 1 (и примите его по конст реф.)

std::ifstream &stream и std::istream &stream имеют один интерфейс, уберите дублирование кода.
1
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
15.04.2013, 14:41 #8
Цитата Сообщение от Wanee Посмотреть сообщение
"8. Программы реализуются на языке С++ БЕЗ использования классов."
Можно всех нае... обмануть. Использовать struct
0
Wanee
54 / 54 / 13
Регистрация: 02.02.2011
Сообщений: 434
15.04.2013, 14:45  [ТС] #9
Tulosba, тогда как задать значение переменной в struct без конструктора?
0
stima
487 / 339 / 39
Регистрация: 22.03.2011
Сообщений: 1,082
Завершенные тесты: 2
15.04.2013, 14:54 #10
C++
1
2
struct Point { int x, y; };
Point point = { 0, 0 };
0
abit
271 / 270 / 34
Регистрация: 03.02.2013
Сообщений: 754
15.04.2013, 14:59 #11
тогда как задать значение переменной в struct без конструктора?
а с чего вы взяли, что у struct нет конструктора? у неё есть всё, что есть у класса (даже наследование)
разница только в одном - class по умолчанию начинает свои методы как private а struct как public
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
15.04.2013, 15:00 #12
Wanee, вся разница между class и struct в c++ в том, что для первого по умолчанию используется private доступ, а для второго - public. Т.е. для структуры можно задавать всё то, что можно для класса, конструктор в том числе.
0
Wanee
54 / 54 / 13
Регистрация: 02.02.2011
Сообщений: 434
15.04.2013, 15:02  [ТС] #13
stima, а как тогда использовать её в throw?

Добавлено через 55 секунд
Tulosba, это да, но если я буду использовать функций и конструкторы в структуре то задание не примут.
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
15.04.2013, 15:04 #14
Wanee, полный текст задания можно узреть?
0
Wanee
54 / 54 / 13
Регистрация: 02.02.2011
Сообщений: 434
15.04.2013, 15:09  [ТС] #15
ТРЕБОВАНИЯ К ПРОГРАММАМ

1. Необходимо точно выполнять условия задач, при сомнениях --
консультироваться с преподавателем. Программы представляются в
исходных текстах.

2. Программы должны быть написаны самостоятельно.

3. Текст программы должен быть откомментирован. В заголовке указать
имя автора, группу, формулировку задания. Имена переменных, функций и
проч. должны иметь осмысленные имена. Желательно объявление переменной
снабжать комментарием о ее назначении.

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

5. Длинные программы (свыше 200 строк) следует разбивать на несколько
файлов и создавать проект. Это обязательное требование, так как
умение работать с проектами квалифицированному программисту
необходимо.

6. Интерфейс программы должен быть достаточно удобен
для пользователя. Программа должна быть снабжена удобным интерфейсом
на базе меню.

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

8. Программы реализуются на языке С++ БЕЗ использования классов.

9. Программы должны быть хорошо протестированы перед сдачей.

10. Сроки сдачи: 1-я программа - до 15 октября,
2-я программа - до 7 ноября,
3-я программа - до 1 декабря,
4-я программа - на зачетной неделе

11. См. также отдельные требования в разделах.

ТРЕБОВАНИЯ к задачам данного раздела:

1. Программа должна осуществлять анализ командной строки. Если при запуске
программе переданы параметры, то первый из них - имя файла, из которого
следует брать исходные данные. Если параметры не переданы, то ввод
осуществляется из стандартного потока ввода.

2. Результат должен представлять собой функцию (отличную от функции main() ),
решающую поставленную задачу. Исходные данные (как правила, матрица и ее
размеры) передаются в эту функцию в качестве параметров.
Функция main() должна быть демонстрацией возможностей написанной программы.
При необходимости можно вводить вспомогательные функции.

и само задание:

16. Среди тех строк целочисленной матрицы, которые содержат только
нечетные элементы, найти строку с максимальной суммой модулей элементов.
0
15.04.2013, 15:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.04.2013, 15:09
Привет! Вот еще темы с ответами:

Работа с памятью - C++
Есть приложение,в нем есть label'ы. Есть ли какая-нибудь возможность средствами C++ допустим, перевести эти контролы? Если есть - дайте...

Работа с памятью - C++
Нужно ривести пример использования операторов new и delete для выделения памяти под двумерный массив и освобождения памяти двумерного...

работа с памятью - C++
Доброго времени суток! У меня возникло затруднение - нужно реализовать на языке Си программу,демонстрирующую распределение памяти таким...

Работа с памятью - C++
Добрый день всем. Я только начал изучение C#(раньше работал c: C++ маленько -т.е. общее представление о нем имею) и у меня вопрос, можно...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru