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

Ошибка при освобождении памяти - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ посоветуйте книжку (на экзамен шпору) http://www.cyberforum.ru/cpp-beginners/thread427879.html
Доброго времяни суток. Посоветуйте пожалуйста книжку на экзамен ( в качестве шпоры) чтоб была понятная и небольшая по основам с++ по началу. Зарание благодарю тех, кто просмотрел тему и решил мне помочь.
C++ Как осуществляется преобразование типов (для чего)? Как осуществляется преобразование типов (для чего)? int *p=(int*)str; // ругается на p Спасибо :) P.s Си http://www.cyberforum.ru/cpp-beginners/thread427868.html
Неименованые каналы C++
Почему при работе с pipe() в отце и сыновьям процессе необходимо закрывать ненужные дискрипторы?
Конструктор копирования C++
Помогите пожалуйста разобраться, необходимо добавить конструктор копирования, теорию знаю, а как на практике применить не знаю. Программа вот - http://zalil.ru/32492444. Добавлено через 33 минуты вот нужный отрывок class List { struct Elem {
C++ Шаблоны C++ http://www.cyberforum.ru/cpp-beginners/thread427864.html
Написал template на С++, но он нифига не компилица, пишет мол типа не могу string в int преобразовать в строчке int out_param = (int)param; #include <stdio.h> #include <conio.h> #include <string> using namespace std; template <typename InType> class Shablon1 { public:
C++ необходимо найти максимальный элемент матрицы используя несколько потоков С++ Добрый день программисты, необходимо выполнить поиск наименьшего элемента матрицы используя количество потоков равное количеству строк данной матрицы. Каждый поток находит минимальный элемент своей строки и записывает его в одномерный массив. а потом оттуда находиться минимальный элемент. кто сможет помочь с поставленной задачей? подробнее

Показать сообщение отдельно
AlexSome
0 / 0 / 0
Регистрация: 14.01.2012
Сообщений: 6
14.01.2012, 05:48     Ошибка при освобождении памяти
Здравствуйте. Знаю, что тема уже много раз поднималась в самых разнообразных местах и с очень отличающимися примерами, но, увы, я тоже с ней столкнулся, и не могу никак найти свою ошибку.

В общем, решил я написать библиотеку длинной арифметики. Так, для себя. Раньше уже таким занимался, но теперь решил сделать всё красиво и через классы. Даже не дойдя до самих арифметических операций, столкнулся с ошибкой при использовании оператора delete.

В общем, вот:

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
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
 
const unsigned int max_digits = 4; // сколько десятичных цифр может поместиться в одном разряде класса number
const unsigned int max_value = 65535; // максимальное значение выбранного типа
 
class number
{
    private:
    unsigned int* base;
    public:
    number();
    number(const number& obj); // конструктор копии
    void clear_nulls(); // очистка незначащих нулей
    void input();
    void output();
    friend bool operator== (number obj1, number obj2);
};
 
number::number() // создание нулевого числа
{
    base = new unsigned int[2];
    base[0] = 1; // длина нулевого числа
    base[1] = 0; // сам ноль
}
 
number::number(const number& obj)
{
    base = new unsigned int [obj.base[0] + 1]; // выделяем столько же памяти (1 для разряда размера)
    for (unsigned int i = 1; i<= base[0]; i++)
        base[i] = obj.base[i]; // копирование разрядов
}
 
void number::clear_nulls()
{
    unsigned int new_n = base[0]; // длина нового слова
    while (base[new_n] == 0)
        new_n--; // доходим до старшего ненулевого разряда
    if (new_n < base[0]) // если есть смысл очищать
    {
        unsigned int* temp_array = new unsigned int [new_n+1]; // создаём новый массив + место для разряда размера
        temp_array[0] = new_n; // он будет новой длины
        for (unsigned int i=1; i<=new_n; i++)
            temp_array[i] = base[i]; // переносим значения из изначального массива
        delete []base; // очищаем изначальный массив
        // так как temp_array очистится при выходе из видимости, то опять выделяем память под base
        // код идентичный коду выше
        base = new unsigned int [new_n+1];
        base[0] = new_n;
        for (unsigned int i=1; i<=new_n; i++)
            base[i] = temp_array[i];
        delete []temp_array;
    }
}
 
void number::input()
{
    delete []base; // очистка предидущего содержания числа
    // т.к. мы не знаем, каких размеров число мы введём, то зададим максимальный
    base = new unsigned int [max_value];
    base[0] = max_value;
    for (unsigned int i=1; i<=max_value; i++)
        base[i] = 0; // обнуление числа
 
    unsigned int signs_count = 0; // число введённых знаков
    char curr_char; // текущий введённый символ
    cin.get(curr_char); // считывание символа
    while (isdigit(curr_char)) // работа до тех пор, пока считанный символ - цифра
    {
        signs_count++; // прибавляем счётчик считанных символов
        unsigned int temp_add; // будет использовать при сдвиге цифр
        temp_add = curr_char - '0'; // изначально равен введённой цифре
        for (unsigned int i=1; i <= ( signs_count-1 ) / max_digits + 1; i++) // (s_c-1) / max_digits + 1 - число разрядов, которые придётся сдвигать (экономия времени)
        {
            base[i] *= 10; // сдвиг разряда влево на 1
            base[i] += temp_add; // вносим в его младший разряд наше число
            temp_add = base[i] / pow(10, max_digits); // делим текущий разряд на его максимальную вместимость (степень десятки)
            base[i] %= (unsigned int)pow(10, max_digits); // откидываем старший (не из имеющихся, а заданный) разряд
        }
        cin.get(curr_char); // считывание следующего символа
    }
 
    this->clear_nulls(); // очищаем незначащие нули
}
 
void number::output()
{
    unsigned int i = base[0]; // старший разряд
    cout << base[i]; // вывели его (без значащих нулей)
    i--; // сместились на разряд влево
    while (i >= 1) // пока не дошли до 0го разряда (количество разрядов)
    {
        cout<<setfill('0')<<setw(max_digits)<<base[i]; // вывели, даже если есть нули
        i--; // смещаемся дальше влево
    }
}
 
bool operator==(number obj1, number obj2)
{
    if (obj1.base[0] != obj2.base[0]) // если не совпадают длины, то это явно не одинаковые числа
        return false;
    else
    {
        unsigned int i = 1;
        bool eq = true; // допускаем, что числа равны
        while (i <= obj1.base[0] && eq) // пока ещё не дошли до конца и пока не опровергли гипотезу о равности
        {
            if (obj1.base[i] == obj2.base[i]) // если в данном месте числа равны - идём дальше
                i++;
            else
                eq = false; // если хоть в одном месте числа не равны - сразу выход
        }
        return eq;
    }
}
 
int main()
{
    number numb1;
    numb1.input();
    number numb2;
    numb2.input();
    cout << boolalpha << (numb1 == numb2);
    cin.get();
    return 0;
}
Код комментировал для себя, надеюсь, и вам будет всё понятно.
При выполнении выдаёт (замечу: ошибка происходит именно на строке "numb2.input();", что есть загадка: первый раз, для первого объекта, всё проходит гладко, а для второго - ошибка):
123
123
*** glibc detected *** /home/alex/CB/long_ar/bin/Debug/long_ar: double free or corruption (out): 0x0804b028 ***
======= Backtrace: =========
/lib/libc.so.6(+0x714ae)[0xb761f4ae]
/lib/libc.so.6(cfree+0x70)[0xb7623050]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb77fbff1]
/usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb77fc04d]
/home/alex/CB/long_ar/bin/Debug/long_ar[0x8048961]
/home/alex/CB/long_ar/bin/Debug/long_ar[0x8048bbf]
/home/alex/CB/long_ar/bin/Debug/long_ar[0x8048d36]
/lib/libc.so.6(__libc_start_main+0xe6)[0xb75c4db6]
/home/alex/CB/long_ar/bin/Debug/long_ar[0x8048791]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:03 1190984 /home/alex/CB/long_ar/bin/Debug/long_ar
0804a000-0804b000 rw-p 00001000 08:03 1190984 /home/alex/CB/long_ar/bin/Debug/long_ar
0804b000-080ac000 rw-p 00000000 00:00 0 [heap]
b7400000-b7421000 rw-p 00000000 00:00 0
b7421000-b7500000 ---p 00000000 00:00 0
b75ab000-b75ae000 rw-p 00000000 00:00 0
b75ae000-b770a000 r-xp 00000000 08:03 403253 /lib/libc-2.13.so
b770a000-b770b000 ---p 0015c000 08:03 403253 /lib/libc-2.13.so
b770b000-b770d000 r--p 0015c000 08:03 403253 /lib/libc-2.13.so
b770d000-b770e000 rw-p 0015e000 08:03 403253 /lib/libc-2.13.so
b770e000-b7711000 rw-p 00000000 00:00 0
b7711000-b772c000 r-xp 00000000 08:03 1053512 /usr/lib/libgcc_s.so.1
b772c000-b772d000 rw-p 0001a000 08:03 1053512 /usr/lib/libgcc_s.so.1
b772d000-b7751000 r-xp 00000000 08:03 403257 /lib/libm-2.13.so
b7751000-b7752000 r--p 00023000 08:03 403257 /lib/libm-2.13.so
b7752000-b7753000 rw-p 00024000 08:03 403257 /lib/libm-2.13.so
b7753000-b7830000 r-xp 00000000 08:03 1054254 /usr/lib/libstdc++.so.6.0.14
b7830000-b7834000 r--p 000dd000 08:03 1054254 /usr/lib/libstdc++.so.6.0.14
b7834000-b7835000 rw-p 000e1000 08:03 1054254 /usr/lib/libstdc++.so.6.0.14
b7835000-b783c000 rw-p 00000000 00:00 0
b7852000-b7854000 rw-p 00000000 00:00 0
b7854000-b7871000 r-xp 00000000 08:03 403295 /lib/ld-2.13.so
b7871000-b7872000 r--p 0001c000 08:03 403295 /lib/ld-2.13.so
b7872000-b7873000 rw-p 0001d000 08:03 403295 /lib/ld-2.13.so
bfd94000-bfdb5000 rw-p 00000000 00:00 0 [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]

Process returned -1 (0xFFFFFFFF) execution time : 1.678 s
Press ENTER to continue.
Должен ещё сказать, что до этого я уже реализовывал эту библиотеку. Но тогда я обошёл проблему не задумываясь, просто не освобождая память (очень срочно надо было её написать, и так проконало). Теперь же второй раз так поступать не хочу, но уже битый час сижу в попытках понять, что я делаю не так.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 01:48. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru