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

Массив, освобождение памяти - C++

Восстановить пароль Регистрация
 
dmmax
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
22.10.2012, 13:18     Массив, освобождение памяти #1
что я сделал не так?


C++ (Qt)
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
#include "stdafx.h"
 
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <clocale>
 
using namespace std;
 
int main(){
    setlocale(LC_ALL, "Russia");
    setlocale(LC_ALL, "rus");
 
    int *a = NULL;
    int menu = 0;
    int n = 0;
    int min = 0, max = 0, tmp = 0;
 
    do{
        cout << "Меню программы." << endl;
        cout << "1. Ввод массива." << endl;
        cout << "2. Показ массива." << endl;
        cout << "3. Замена максимального на минимальный." << endl;
        cout << "-----------------------------" << endl;
        cout << "0. Выход" << endl;
        cout << "-----------------------------" << endl;
 
        cin >> menu;
        switch(menu){
            case 1:
                {
                    cout << "Введите размер массива n" << endl;
                    cin >> n;
                    int * a = new int[n];
                        for(int i = 0; i < n; ++i){
                            cin >> a[i]; 
                        }
                }
 
                break;
            case 2:
                {
                    for(int i = 0; i < n; ++i){
                        cout << a[i] << endl;
                    }
                }
                break;
            case 3:
                {
                    for(int i = 0; i < n; ++i){
                        if(min < a[i]){
                            min = a[i];
                        }
                        if(max > a[i]){
                            max = a[i];
                        }
                    }
                    tmp = max;
                    max = min;
                    min = tmp;
 
                    cout << "max = " << max << "min = " << min << endl;
                }
                break;
            case 0:
                break;
            default:
                cout << "Вы ввели неверное значение!" << endl;
        }
    }while(menu != 0);
    
    delete [] a;
    getchar();
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
22.10.2012, 13:53     Массив, освобождение памяти #2
Два раза объявил a.
C++
1
2
3
4
5
6
7
8
9
    int *a = NULL;
    int menu = 0;
 
    do{
                    int * a = new int[n];
    // ... 
    }while(menu != 0);
    // ...
    delete [] a;
Ну и удаляешь не ту а, которая указывает на созданный массив, а ту, которая объявлена в начале, которая вообще ни на что не указывает.
Короче, убери int * перед int * a = new int[n]; и будет я-я-фантастиш.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,722
Записей в блоге: 3
22.10.2012, 13:53     Массив, освобождение памяти #3
Цитата Сообщение от dmmax Посмотреть сообщение
что я сделал не так?

C++ (Qt)
1
2
3
4
    setlocale(LC_ALL, "Russia");//оставьте одну функцию локализации, эту
    setlocale(LC_ALL, "rus");//или эту
    for(int i = 0; i < n; ++i)// попробуйте лучше i++ вместо ++i (во всех циклах)
}
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
22.10.2012, 13:55     Массив, освобождение памяти #4
Цитата Сообщение от IGPIGP Посмотреть сообщение
// попробуйте лучше i++ вместо ++i (во всех циклах)
Зачем?
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,722
Записей в блоге: 3
22.10.2012, 14:09     Массив, освобождение памяти #5
Цитата Сообщение от John Prick Посмотреть сообщение
Зачем?
исключительно для самодисциплины. Тут, конкретно, всё равно.
dmmax
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
22.10.2012, 14:18  [ТС]     Массив, освобождение памяти #6
Цитата Сообщение от John Prick Посмотреть сообщение
Два раза объявил a.
Короче, убери int * перед int * a = new int[n]; и будет я-я-фантастиш.
Не компилиться )
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
22.10.2012, 14:21     Массив, освобождение памяти #7
Цитата Сообщение от IGPIGP Посмотреть сообщение
исключительно для самодисциплины.
Не совсем понятно в чём самодисциплина. Постфиксный инкремент в общем случае создаёт временный объект, а значит менее эффективнее префиксного. Зачем "самодисциплинироваться" на написание менее эффективного кода? В случае с int конечно всё равно, но если это будет какой-нить хитрый итератор, то тут уже могут возникнуть проблемы.

Добавлено через 1 минуту
Цитата Сообщение от dmmax Посмотреть сообщение
Не компилиться )
Интересно посмотреть, что и как ты там исправил.
dmmax
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
22.10.2012, 14:44  [ТС]     Массив, освобождение памяти #8
C++ (Qt)
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
#include "stdafx.h"
 
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <clocale>
 
using namespace std;
 
int main(){
    setlocale(LC_ALL, "Russia");
    setlocale(LC_ALL, "rus");
 
    int * a = NULL;
    int menu = 0;
    int n = 0;
    int min = 0, max = 0, tmp = 0;
 
    do{
        cout << "Меню программы." << endl;
        cout << "1. Ввод массива." << endl;
        cout << "2. Показ массива." << endl;
        cout << "3. Замена максимального на минимальный." << endl;
        cout << "-----------------------------" << endl;
        cout << "0. Выход" << endl;
        cout << "-----------------------------" << endl;
 
        cin >> menu;
        switch(menu){
            case 1:
                {
                    cout << "Введите размер массива n" << endl;
                    cin >> n;
                    a = new int[n];
                        for(int i = 0; i < n; ++i){
                            cin >> a[i]; 
                        }
                }
 
                break;
            case 2:
                {
                    for(int i = 0; i < n; ++i){
                        cout << a[i] << endl;
                    }
                }
                break;
            case 3:
                {
                    for(int i = 0; i < n; ++i){
                        if(min < a[i]){
                            min = a[i];
                        }
                        if(max > a[i]){
                            max = a[i];
                        }
                    }
                    tmp = max;
                    max = min;
                    min = tmp;
 
                    cout << "max = " << max << "min = " << min << endl;
                }
                break;
            case 0:
                break;
            default:
                cout << "Вы ввели неверное значение!" << endl;
        }
    }
    while(menu != 0);
    
    delete [] a;
    getchar();
    return 0;
}
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
22.10.2012, 14:58     Массив, освобождение памяти #9
У меня этот код прекрасно компилируется.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,722
Записей в блоге: 3
22.10.2012, 16:20     Массив, освобождение памяти #10
Цитата Сообщение от John Prick Посмотреть сообщение
Не совсем понятно в чём самодисциплина. Постфиксный инкремент в общем случае создаёт временный объект, а значит менее эффективнее префиксного. Зачем "самодисциплинироваться" на написание менее эффективного кода? В случае с int конечно всё равно, но если это будет какой-нить хитрый итератор, то тут уже могут возникнуть проблемы.
Да в спешке написал. Видно много сообщений было и нашел пост на второй странице. Ничего не увидел, но решил поднять наверх. А спешка нужна при ловле блох.
Теперь о временных объектах. Поскольку параметры цикла, - его локальные переменные, то копия создается всегда и от формы инкрементирования это не зависит:
C++
1
2
3
4
5
6
7
8
int i=123;
for(int i=0; i<5;++i){
cout<<endl; 
cout<<"i= "<<i; 
cout<<endl;
}
cout<<"i= "<<i; //123
cout<<endl;
Поэтому использование объекта не имеющего корректных конструктора копирования и деструктора в качестве локальной переменной (параметра цикла в частности), мягко говоря нехорошо.
Но когда видишь:
C++
1
2
3
4
5
for(;;){
int i=0;
if(i<123)break;
mass[++i]=i;
}
и вопрос: это же аналогично:
C++
1
for(int i=0; i<123;++i){....}
Хочется, порой, ещё до полуночи выпустить когти, обрасти шерстью и зарычать:-"Не-е-ет!"(шучу )
Конечно про "самодисциплину" я зря. Делать можно, в принципе всё, если знаешь что.
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
22.10.2012, 17:22     Массив, освобождение памяти #11
Цитата Сообщение от IGPIGP Посмотреть сообщение
Поскольку параметры цикла, - его локальные переменные, то копия создается всегда и от формы инкрементирования это не зависит
Как бы совсем не то.

C++
1
2
3
4
5
6
7
8
9
10
func(++i);
// эквивалентно:
i = i + 1;
func(i);
 
func(i++);
// 'эквивалентно:
int temp = i;
i = i + 1;
func(temp);
Для отдельно стоящего i++ компилятор не станет генерировать временный объект, хотя и может. Если же вместо int задействован некий объект пользовательского типа, то без временного объекта вообще не обойтись.
C++
1
2
3
4
5
6
7
8
9
10
11
12
class T
{
    T & operator++() {
        // тут действия по инкременту
        return *this;
    }
    T operator++(int) {
        T temp = *this;
        // тут действия по инкременту
        return temp;
    }
};
Кроме временного объекта ещё конструктор копирования вызывается и оператор =.

Добавлено через 6 минут
В вашем примере:
C++
1
2
3
4
5
for(;;){
int i=0;
if(i<123)break;
mass[++i]=i;
}
на каждой итерации i будет инициализироваться нулём. А условие всегда будет прерывать цикл.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,722
Записей в блоге: 3
22.10.2012, 17:39     Массив, освобождение памяти #12
Цитата Сообщение от John Prick Посмотреть сообщение
В вашем примере:
C++
1
2
3
4
5
for(;;){
int i=0;
if(i<123)break;
mass[++i]=i;
}
на каждой итерации i будет инициализироваться нулём. А условие всегда будет прерывать цикл.
Верно. Лучше бы:
C++
1
2
3
4
for(int i=0;;){
if(i<123)break;
mass[++i]=i;
}
Цитата Сообщение от John Prick Посмотреть сообщение
вместо int задействован некий объект пользовательского типа, то без временного объекта вообще не обойтись.
C++
1
2
3
4
5
6
7
8
9
10
11
12
class T
{
    T & operator++() {
        // тут действия по инкременту
        return *this;
    }
    T operator++(int) {
        T temp = *this;
        // тут действия по инкременту
        return temp;
    }
};
Кроме временного объекта ещё конструктор копирования вызывается и оператор =.
Вы имеете ввиду случай когда объект приводится к целому типу (полю для которого перегружены ++)?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.10.2012, 19:37     Массив, освобождение памяти
Еще ссылки по теме:

C++ Освобождение памяти в c++
C++ Освобождение памяти
Освобождение памяти, выделенной на динамический массив структур C++

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

Или воспользуйтесь поиском по форуму:
John Prick
754 / 687 / 123
Регистрация: 27.07.2012
Сообщений: 1,974
Завершенные тесты: 3
22.10.2012, 19:37     Массив, освобождение памяти #13
Цитата Сообщение от IGPIGP Посмотреть сообщение
Вы имеете ввиду случай когда объект приводится к целому типу (полю для которого перегружены ++)?
Нет, никакого приведения к целому типи я не имею ввиду. Здесь я указал пример реализации объекта, который может быть использован вместо целочисленного счётчика в цикле for. Например, так:
C++
1
2
for (T i = begin; i != end; ++i) {/*...*/}
for (T i = begin; i != end; i++) {/*...*/}
Понимаете, в чём разница? Какой оператор ++ будет вызван в каком случае?
С int примерно та же канитель, с той лишь разницей, что отдельно стоящий i++ компилятор, скорее всего, оптимизирует, убрав создание временной переменной, и никакой разницы с ++i не останется.

Ну и опять же в вашем примере ошибка:
C++
1
2
3
4
for(int i=0;;){
if(i<123)break;
mass[++i]=i;
}
первое значение i - ноль. Выполнится условие if (i < 123) и цикл прервётся по break.
Если вы хотели эквивалентрную запись, нужно было так:
C++
1
2
3
4
5
6
7
8
9
    {// локальная область видимости цикла for
        int i = 0;
        for (;;)
        {
            if (i == 123) break;
            mas[i] = i;
            ++i;
        }
    }
Yandex
Объявления
22.10.2012, 19:37     Массив, освобождение памяти
Ответ Создать тему
Опции темы

Текущее время: 14:35. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru