0 / 0 / 0
Регистрация: 04.12.2012
Сообщений: 13
1

Ошибка в работе с памятью

07.05.2013, 19:15. Показов 799. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
После использования программы и последующего выхода из нее возникает ошибка HEAP CORRUPTION DETECTED.
Хотелось бы узнать, в чем причина и как в данном случае правильно выделить и освободить память.
Был бы очень признателен, если б кто-нибудь смог отработать программу и указать на допущенные ошибки, т.к. очень нужно чтобы программа работала гладко, без ошибок.
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
#include "stdafx.h"
#include "iostream"
#include "Stack.h" // библиотека "Стек"
 
using namespace std;
 
int main()
{
    int choice; // Выбор операции над стеком
    Stack st; // Создаем стек
    bool quit = true; // если false, выходим из цикла
 
    while (quit == true)
    {
        cout << "(0)Quit (1)Push (2)Pop (3)Show (4)Tail: ";
        cin >> choice; // номер операции
 
        switch (choice)
        {
        case 1: // Добавить элемент в стек
            st.Push();
            st.Show();
            break;
 
        case 2: // Извлечь элемент из стека
            st.Pop();
            st.Show();
            break;
 
        case 3: // Показать текущие значения элементов стека
            st.Show();
            break;
 
        case 4: // Показать вершину стека (последний элемент)
            st.Tail();
            break;
 
        default: // В остальных случаях выходи из цикла
            quit = false;
            break;
        }
    }
 
    system("pause"); // стоп-консоль
 
    return 0;
}
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
// ==================================== Stack ======================================
// 
// Класс Stack - реализует структуру данных "стек", 
// позволяет оперировать символьными данными.
// При каждом проталкивании в "стек" элемент записывается в массив char'ов,
// а length увеличивается на единицу.
// При извлечении элемента из "стека" length уменьшается на единицу.
//
// =================================================================================
 
 
class Stack
{
public:
    Stack();                // конструктор, инициализирует length нулевым значением,
                            // выделяет память для data
    ~Stack();               // деструктор, освобождает память, выделенную под data
    void Push();            // проталкивание элемента в стек
                            // увеличивает length на 1
    void Pop();             // извлечение элемента из стека
                            // уменьшает length на 1
    void Tail();            // отображает вершину стека
    void Show() const;      // отображает эелементы стека
 
private:
    char *data; // элементы стека
    int length; // длина стека
};
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
#include "stdafx.h"
#include "iostream"
#include "Stack.h"
 
using namespace std;
 
Stack::Stack():
    length(0), // инициализация нулевой длины стека
    data(new char[])
{}
 
Stack::~Stack()
{
    delete[] data;
    data = 0;
}
 
void Stack::Push() // добавление элемента в стек
{
    char element; // элемент стека
 
    cout << "New element: "; // приглашение добавить элемент в стек
    cin >> element;
 
    data[length] = element; // эелементы храним в массиве
    length++; // при добавлении элемента увеличиваем длину стека
}
 
void Stack::Pop() // извлечение элемента из стека
{
    if (length > 0) // если стек не пустой, извлекаем элемент
    {
        cout << "Pop element: " << data[length - 1] << endl;
        length--;
    }
    // иначе - сообщение о пустом стеке в функции Show()
}
 
void Stack::Tail() // отображаем вершину стека
{
    if (length > 0) // если стек не пустой,
    {
        cout << "Tail element: " << data[length - 1] << endl;
        // отображаем вершину стека
    }
    else // если пустой,
    {
        cout << "Stack is empty!" << endl;
    }
}
 
void Stack::Show() const
{
    if (length > 0) // если стек не пустой,
    {
        for (int i = 0; i < length; i++)
        {
            cout << data[i]; // отображаем все эелементы
            if (i != length - 1) // после каждого элемента, кроме последнего
            {
                cout << ", "; // ставим запятую
            }
            else // если элемент последний,
            {
                cout << endl; // то перевод строки
            }
        }
    }
    else // если стек пустой
    {
        cout << "Stack is empty!" << endl;
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.05.2013, 19:15
Ответы с готовыми решениями:

Ошибка при работе с памятью
Есть класс, в котором я предпринимаю безрезультатные попытки работать с динамической памятью из-за...

Ошибка при работе с памятью
Написан следующий код: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;stdio.h&gt; #include...

Ошибка при работе с памятью
Если ввести например 6, 0, чтобы выбросить исключение. То по завершение программы выскакивает...

Ошибка с памятью при работе с двумерными массивами.
{ int i, j, c, kol; n=StrToInt(Edit1-&gt;Text); m=StrToInt(Edit2-&gt;Text); for(i=0; i&lt;n; i++) { ...

4
...
1906 / 1326 / 965
Регистрация: 12.02.2013
Сообщений: 2,171
07.05.2013, 19:55 2
Tim Berg, сразу вопрос к вам: по вашему мнению сколько выделится памяти в конструкторе под поле data? Я не знаю как MS компилятор ведёт себя, но gcc сразу ругнулся. Как я понимаю, это аналог new char[0] (т.е. тогда проще data(NULL)), но я могу и ошибаться. Но в любом случае, вы в методе Push спокойно и без всяких сомнений добавляете элементы: data[length++] = element. И теперь опять возвращаюсь к вопросу: так сколько вы выделили памяти под data?
0
0 / 0 / 0
Регистрация: 04.12.2012
Сообщений: 13
07.05.2013, 22:46  [ТС] 3
Могу написать глупость, но, как мне кажется, такой прием приемлим, т.к. это динамический массив (или нет?) и я могу добавить столько элементов, сколько мне позже понадобится.
С++ уже плохо помню, надо вспоминать.
На VS у меня компилируется, работает и ошибка вылетает только по окончании работы программы.
0
...
1906 / 1326 / 965
Регистрация: 12.02.2013
Сообщений: 2,171
08.05.2013, 04:19 4
Цитата Сообщение от Tim Berg Посмотреть сообщение
Могу написать глупость, но, как мне кажется, такой прием приемлем
Не обижайтесь, но вы написали глупость.

Цитата Сообщение от Tim Berg Посмотреть сообщение
динамический массив
А что есть динамический массив? Вы объявляете char* data - это ничто иное как просто указатель на область памяти. Когда вы пишите, к примеру, data = new char[10] тем самым вы выделяете (резервируете) память размером sizeof(char) * 10 (т.е 10 байт) и адрес на начало этого вектора (выделенного участка памяти) присваиваете data. Контроль выхода за границы выделенной памяти никто кроме вас осуществлять не будет. Я не знаю сколько MS компилятор выделит памяти при такой записи new char[], но в любом случае это либо 0, либо 1.

Цитата Сообщение от Tim Berg Посмотреть сообщение
и я могу добавить столько элементов, сколько мне позже понадобится.
Эх, если бы всё было так просто!

Цитата Сообщение от Tim Berg Посмотреть сообщение
работает и ошибка вылетает только по окончании работы программы
Ваши действия из разряда Undefined behavior. Если бы вы попробовали поработать с большим количеством символов, то ваша программа вылетела бы раньше.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
08.05.2013, 09:53 5
Цитата Сообщение от anmartex Посмотреть сообщение
выделит памяти при такой записи new char[], но в любом случае это либо 0, либо 1.
MS генерит в таком случае код, эквивалентный new char[0]. Не очень понятно, почему они разрешают не писать число в скобках, ну, пусть это будет на их совести.
1
08.05.2013, 09:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.05.2013, 09:53
Помогаю со студенческими работами здесь

Ошибка в коде при работе с динамической памятью
Не могу понят что не так ? При вводе в динамический массив А последовательность &quot;61 3 2 0 -2 -25...

Ошибка с памятью при работе класса и map
В общем есть класс тест class test { public: test(void); ~test(void); test(const int&amp;);...

Ошибка с памятью при работе с динамическим двумерным массивом
Вроде всё правильно, но в ходе работы программа выдаёт ошибку(на скрине). Дело в двумерном...

Управление динамической памятью при работе с классами
Всем привет! Есть очень сложный класс, внутри которого есть куча указателей, в его конструкторе...


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

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

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