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

Выделение памяти - C++

Восстановить пароль Регистрация
 
Ryabchik
17 / 17 / 1
Регистрация: 09.01.2013
Сообщений: 158
16.06.2013, 19:08     Выделение памяти #1
Доброго всем вечера. В книжке нашел задание: определить класс, представляющий стек.
Сделал так, что при заполнении всего стека, динамически выделяется новая память и все элементы стека туда копируются. Но почему то выдает ошибку (прикладываю скрин).

Вот класс
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 <new>
 
using std :: cout;
using std :: bad_alloc;
 
const int FIRST (10); //первоначальный размер стека
 
class STACK
{
    int *pstack;
    int recorded; //число записанных в стек элементов
    int size; //размер стека
 
public:
    STACK (int n)
    {
        pstack = new int [FIRST];
        *pstack = n;
        size = FIRST;
        recorded = 0;
    }
 
    int pop (); //удаляем верхний элемент
    int push (int n); //записываем верхний
    int print (); //выводим все
    int peek (); //выодим нижний
};
 
int STACK :: pop ()
{
    if (recorded = 0)
        cout << "\nОшибка! Стек пуст\n";
 
    else
    {
        cout << '\n' << *(pstack + recorded) << " удален из стека" << '\n';
        for (int i = 0, k = 1; k < recorded; i ++, k ++)
        {
            *(pstack + i) = *(pstack + k);
        }
    }
 
    recorded --; //минус один элемент
 
    system ("pause");
    return 0;
}
 
int STACK :: push (int n)
{
    if (recorded < size) //если стек не полон
    {
        recorded ++;
        *(pstack + recorded) = n;
    }
 
    if (recorded == size)
    {
        cout << "\nСтек заполнен. Выделяется новая память...\n";
        int *phelp;
 
        try
        {
            phelp = new int [FIRST * 2]; //выделяем новую память
            cout << "\nПамять выделена успешно\n";
        }
 
        catch (bad_alloc &ex)
        {
            cout << "\nНе удалось выделить память\n"
                << ex.what () << '\n';
            delete [] phelp;
        }
 
        for (int i = 1; i < FIRST; i ++) //копируем из старого стека во вспомогательный массив
            *(phelp + i) = *(pstack + i);
 
        delete [] pstack;
        pstack = nullptr;
 
        pstack = phelp;
 
        delete [] phelp;
        phelp = nullptr;
 
        cout << "\nУвеличение стека прошло успешно\n";
        recorded ++;
 
        system ("pause");
    }
 
    return 0;
}
 
int STACK :: print ()
{
    cout << "\nЭлементы стека: ";
 
    for (int i = 0; i < (recorded + 1); i ++)
    {
        cout << *(pstack + i) << " ";
    }
 
    cout << "." << '\n';
    system ("pause");
    return 0;
}
 
int STACK :: peek ()
{
    cout << "\nНижний элемент стека: " << *pstack << '\n';
 
    system ("pause");
    return 0;
}
Ну и на всякий пожарный - main:
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
#include <iostream>
#include <windows.h>
 
#include "Class_stack.h"
 
using std :: cin;
using std :: cout;
 
int main ()
{
    SetConsoleCP (1251);
    SetConsoleOutputCP (1251);
 
    cout << "Доброго времени суток.\nЭта программа работает со стеком целочисленных значений\n"
        <<"Введите первый элемент стека: ";
 
    int first;
    cin >> first;
 
    STACK s (first);
    
    int choice = 1;
    while (choice)
    {
        system ("CLS");
 
        cout << "1 - удалить элемент\n"
            << "2 - добавить элемент\n"
            << "3 - вывести все элементы\n"
            << "4 - вывести нижний элемент\n"
            << "0 - выход\n";
        cin >> choice;
 
        if (choice == 1)
            s.pop ();
 
        if (choice == 2)
        {
            cout << "\nВведите новый элемент стека (целое число): ";
            int number;
            cin >> number;
            s.push (number);
        }
 
        if (choice == 3)
            s.print ();
 
        if (choice == 4)
            s.peek ();
    }
 
    return 0;
}
Кстати, если видны признаки индусокода или вы считаете, что что-то можно сделать проще, буду рад любой конструктивной критике))
Миниатюры
Выделение памяти  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.06.2013, 19:08     Выделение памяти
Посмотрите здесь:

C++ выделение памяти
C++ Выделение памяти...
Выделение памяти C++
C++ Не выделение памяти
Выделение памяти C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 2
16.06.2013, 19:32     Выделение памяти #2
C++
1
2
3
4
5
6
        delete [] pstack;//основной массив почистил
        pstack = NULL;//занулил указатель
 
        pstack = phelp;//указатель на основной массив указывает на новый
 
        delete [] phelp;//но phelp все ещё указывает на область памяти нового массива, а ты его удаляешь
Ryabchik
17 / 17 / 1
Регистрация: 09.01.2013
Сообщений: 158
16.06.2013, 20:09  [ТС]     Выделение памяти #3
Кудаив, если я в сперва обнулю указатель на новый массив, а потом его (массив) удалю, то та же ошибка.
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 2
16.06.2013, 20:13     Выделение памяти #4
C++
1
2
3
4
delete [] pstack;//основной массив почистил
        pstack = NULL;//занулил указатель
 
        pstack = phelp;
Цитата Сообщение от Ryabchik Посмотреть сообщение
а потом его (массив) удалю
не надо очищать массив на который указывает phelp
Ryabchik
17 / 17 / 1
Регистрация: 09.01.2013
Сообщений: 158
16.06.2013, 20:17  [ТС]     Выделение памяти #5
Цитата Сообщение от Кудаив Посмотреть сообщение
не надо очищать массив на который указывает phelp
Я ведь обнуляю указатель на него и потом очищаю.
А если стек опять заполнится и память выделится еще раз? и еще раз? и еще раз? и закончится?
Ведь надо удалять динамическое безобразие после применения?
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 2
16.06.2013, 20:29     Выделение памяти #6
ты удаляешь старый массив который стал тесен, и присваеваешь указателю, инкапсулирующий массив в классе -стеке, новый массив по-просторнее - в итоге оба указателя pstack и phelp на новый массив, при выходе из метода push указатель phelp аннигилирует
Ryabchik
17 / 17 / 1
Регистрация: 09.01.2013
Сообщений: 158
16.06.2013, 20:34  [ТС]     Выделение памяти #7
Кудаив, спасибо, дошло))
Но если я уберу
Цитата Сообщение от Кудаив Посмотреть сообщение
delete [] phelp;
ошибка все равно остается((
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 2
16.06.2013, 20:41     Выделение памяти #8
вот тебе ещё ошибка
C++
1
2
if (recorded = 0)//!!!
        cout << "\nОшибка! Стек пуст\n";
Ryabchik
17 / 17 / 1
Регистрация: 09.01.2013
Сообщений: 158
16.06.2013, 20:46  [ТС]     Выделение памяти #9
Цитата Сообщение от Кудаив Посмотреть сообщение
вот тебе ещё ошибка
Это вряд ли связано с памятью, но все равно спасибо.
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 2
16.06.2013, 20:52     Выделение памяти #10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
if (recorded == 0)
        cout << "\nОшибка! Стек пуст\n";
 
    else
    {
        cout << '\n' << *(pstack + recorded) << " удален из стека" << '\n';
        for (int i = 0, k = 1; k < recorded; i ++, k ++)
        {
            *(pstack + i) = *(pstack + k);
        }
    }
 
    recorded --; /*стек пуст а текущей размер уменьшается*/
Добавлено через 2 минуты
Цитата Сообщение от Ryabchik Посмотреть сообщение
Это вряд ли связано с памятью
это связано с памятью напрямую ибо дальше то идёт блок выталкивания из стека

Добавлено через 4 минуты
C++
1
2
for (int i = 1; i < FIRST; i ++) //копируем из старого стека во вспомогательный массив
            *(phelp + i) = *(pstack + i);
а почему собсна с i = 1 ?
Ryabchik
17 / 17 / 1
Регистрация: 09.01.2013
Сообщений: 158
16.06.2013, 20:54  [ТС]     Выделение памяти #11
Ну да. Тогда и recorded неплохо бы единичкой инициализировать, а не нулем. Блин, ну тогда все посыпалось...

Добавлено через 1 минуту
Цитата Сообщение от Кудаив Посмотреть сообщение
а почему собсна с i = 1 ?
Мда. Там были попытки... Неважно.
Кудаив
328 / 405 / 24
Регистрация: 27.05.2012
Сообщений: 1,162
Завершенные тесты: 2
16.06.2013, 20:57     Выделение памяти #12
C++
1
2
phelp = new int [FIRST * 2]; //выделяем новую память
            cout << "\nПамять выделена успешно\n";
сработает 1 раз, при следующем разе выделится память 20 ячеек, потом опять 20 и опять 20
лучше уж
C++
1
2
 [CPP]phelp = new int [size * 2]; //выделяем новую память
            cout << "\nПамять выделена успешно\n";
[/CPP]
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.06.2013, 21:02     Выделение памяти
Еще ссылки по теме:

Выделение памяти C++
Выделение памяти C++
C++ выделение памяти

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

Или воспользуйтесь поиском по форуму:
Ryabchik
17 / 17 / 1
Регистрация: 09.01.2013
Сообщений: 158
16.06.2013, 21:02  [ТС]     Выделение памяти #13
Уже все. Из-за этих маленьких изменений, все посыпалось. Значения не хотят удалятся и т.д.
Код уходит на доработку.
Кудаив, спасибо большое за помощь)
Yandex
Объявления
16.06.2013, 21:02     Выделение памяти
Ответ Создать тему
Опции темы

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