Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
19 / 20 / 0
Регистрация: 09.01.2013
Сообщений: 168
1

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

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

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

Вот класс
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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.06.2013, 19:08
Ответы с готовыми решениями:

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

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

Выделение памяти(С = С++)
Привет. Нужна помощь, в выделении памяти. Есть код на С, нужно перевести его в С++. int...

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

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

Добавлено через 1 минуту
Цитата Сообщение от Кудаив Посмотреть сообщение
а почему собсна с i = 1 ?
Мда. Там были попытки... Неважно.
0
419 / 418 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
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
19 / 20 / 0
Регистрация: 09.01.2013
Сообщений: 168
16.06.2013, 21:02  [ТС] 13
Уже все. Из-за этих маленьких изменений, все посыпалось. Значения не хотят удалятся и т.д.
Код уходит на доработку.
Кудаив, спасибо большое за помощь)
0
16.06.2013, 21:02
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.06.2013, 21:02
Помогаю со студенческими работами здесь

Выделение памяти
Доброго времени суток. Чтобы выделить память под двумерный массив в такой форме: //n -...

Выделение памяти...
Вот решил себе ликбез устроить и возникли вопросы: 1) Почему char* p = &quot;fffff&quot;; не реагирует...

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

Выделение памяти
int main() { FILE *fIn = NULL, *fOut =NULL; Error EMyError; CNodeStack *Start; CNodeStack...


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

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