Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
Ryabchik
18 / 19 / 0
Регистрация: 09.01.2013
Сообщений: 164
#1

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

16.06.2013, 19:08. Просмотров 501. Ответов 12
Метки нет (Все метки)

Доброго всем вечера. В книжке нашел задание: определить класс, представляющий стек.
Сделал так, что при заполнении всего стека, динамически выделяется новая память и все элементы стека туда копируются. Но почему то выдает ошибку (прикладываю скрин).

Вот класс
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;
}
Кстати, если видны признаки индусокода или вы считаете, что что-то можно сделать проще, буду рад любой конструктивной критике))
0
Миниатюры
Выделение памяти  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.06.2013, 19:08
Ответы с готовыми решениями:

Распределение памяти. Динамическое выделение памяти
an-1 an-2 ... a2

Выделение памяти, проверка на утечку памяти
Интересуют два вопроса: 1. Правильно ли устроен алгоритм выделения, удаление...

Выделение памяти
В чём ошибка выделения памяти? Подскажите, друзья! #include &quot;stdafx.h&quot;...

Выделение памяти
Платформа и компилятор x64. Установлено 64Gb ОЗУ, 60Gb из них откусил SQL...

Выделение памяти
Можно ли сделать так, чтобы в memory выделилась память для 5 int объектов, а...

12
Кудаив
410 / 409 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 2
16.06.2013, 19:32 #2
C++
1
2
3
4
5
6
        delete [] pstack;//основной массив почистил
        pstack = NULL;//занулил указатель
 
        pstack = phelp;//указатель на основной массив указывает на новый
 
        delete [] phelp;//но phelp все ещё указывает на область памяти нового массива, а ты его удаляешь
1
Ryabchik
18 / 19 / 0
Регистрация: 09.01.2013
Сообщений: 164
16.06.2013, 20:09  [ТС] #3
Кудаив, если я в сперва обнулю указатель на новый массив, а потом его (массив) удалю, то та же ошибка.
0
Кудаив
410 / 409 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 2
16.06.2013, 20:13 #4
C++
1
2
3
4
delete [] pstack;//основной массив почистил
        pstack = NULL;//занулил указатель
 
        pstack = phelp;
Цитата Сообщение от Ryabchik Посмотреть сообщение
а потом его (массив) удалю
не надо очищать массив на который указывает phelp
0
Ryabchik
18 / 19 / 0
Регистрация: 09.01.2013
Сообщений: 164
16.06.2013, 20:17  [ТС] #5
Цитата Сообщение от Кудаив Посмотреть сообщение
не надо очищать массив на который указывает phelp
Я ведь обнуляю указатель на него и потом очищаю.
А если стек опять заполнится и память выделится еще раз? и еще раз? и еще раз? и закончится?
Ведь надо удалять динамическое безобразие после применения?
0
Кудаив
410 / 409 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 2
16.06.2013, 20:29 #6
ты удаляешь старый массив который стал тесен, и присваеваешь указателю, инкапсулирующий массив в классе -стеке, новый массив по-просторнее - в итоге оба указателя pstack и phelp на новый массив, при выходе из метода push указатель phelp аннигилирует
0
Ryabchik
18 / 19 / 0
Регистрация: 09.01.2013
Сообщений: 164
16.06.2013, 20:34  [ТС] #7
Кудаив, спасибо, дошло))
Но если я уберу
Цитата Сообщение от Кудаив Посмотреть сообщение
delete [] phelp;
ошибка все равно остается((
0
Кудаив
410 / 409 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 2
16.06.2013, 20:41 #8
вот тебе ещё ошибка
C++
1
2
if (recorded = 0)//!!!
        cout << "\nОшибка! Стек пуст\n";
0
Ryabchik
18 / 19 / 0
Регистрация: 09.01.2013
Сообщений: 164
16.06.2013, 20:46  [ТС] #9
Цитата Сообщение от Кудаив Посмотреть сообщение
вот тебе ещё ошибка
Это вряд ли связано с памятью, но все равно спасибо.
0
Кудаив
410 / 409 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 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 ?
0
Ryabchik
18 / 19 / 0
Регистрация: 09.01.2013
Сообщений: 164
16.06.2013, 20:54  [ТС] #11
Ну да. Тогда и recorded неплохо бы единичкой инициализировать, а не нулем. Блин, ну тогда все посыпалось...

Добавлено через 1 минуту
Цитата Сообщение от Кудаив Посмотреть сообщение
а почему собсна с i = 1 ?
Мда. Там были попытки... Неважно.
0
Кудаив
410 / 409 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 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]
1
Ryabchik
18 / 19 / 0
Регистрация: 09.01.2013
Сообщений: 164
16.06.2013, 21:02  [ТС] #13
Уже все. Из-за этих маленьких изменений, все посыпалось. Значения не хотят удалятся и т.д.
Код уходит на доработку.
Кудаив, спасибо большое за помощь)
0
16.06.2013, 21:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.06.2013, 21:02

выделение памяти
Здравствуйте, помогите пожалуйста исправить ошибку, это лишь малая часть кода. ...

Выделение памяти.
Значит так.Задача такая. Ввести строки или строку символов. Сколько мы будем...

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


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

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

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