Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Утечка памяти 
:(
    Опции темы
kleks
Дата 7.4.2006, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.10.2005

Репутация: нет
Всего: нет



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

BigInt::BigInt(char *str)
{
    nol=0;
    long i, j;
    int tCelLen, tDrobLen, s;
char* ZapyatPos=strchr (str, ',');
    s=strlen(str);
    if (ZapyatPos==NULL)
    {
        droblen=0;
        tDrobLen=0;
        zposition=-1;
    }
    else
    {
        tDrobLen=&str[s]-(ZapyatPos+1);
    }
    
        
    if (str[0]=='-')
    {
        if (ZapyatPos==NULL)
        {
            sign=-1;
            tCelLen=s-1;
        }
        else
        {
            sign=-1;
            tCelLen=ZapyatPos-str-1;
            zposition=tCelLen+1;
        }
    }
    else
    {
        if (ZapyatPos==NULL)
        {
            sign=1;
            tCelLen=s;
        }
        else
        {
            sign=1;
            tCelLen=ZapyatPos-str;
            zposition=tCelLen;
        }
    }
    
    if (tCelLen<0) tCelLen=0;
    if (tDrobLen<0) tDrobLen=0;

    
    cellen=tCelLen;
    cel= new unsigned char [cellen];
    memset(cel,0,cellen);
    
    droblen=tDrobLen;
    drob= new unsigned char[droblen];
    memset(drob,0,droblen);
    
    if (tCelLen>0 && tDrobLen>0)
    {
    
    if (sign==-1)
    {
        for (i=1; i<=tCelLen; i++) {cel[i-1]=str[i]; cel[i]='\0';}
        for (i=0, j=tCelLen+2; i<=tDrobLen-1, j<=s; i++, j++) {drob[i]=str[j];}
    }

    else  
    {
        for (i=0; i<=tCelLen-1; i++) {cel[i]=str[i]; cel[i+1]='\0';}
        for (i=0, j=tCelLen+1; i<=tDrobLen-1, j<=s; i++, j++) drob[i]=str[j];
    }
    
    cout<<cel;
    cout<<",";
    cout<<drob;
    }

    if (tCelLen==0 && tDrobLen>0)
    {
        if (sign==-1) for (i=0, j=2; i<=tDrobLen-1, j<=s; i++, j++) drob[i]=str[j];
        else for (i=0, j=1; i<=tDrobLen-1, j<=s; i++, j++) drob[i]=str[j];
        cout<<",";
        cout<<drob;
    }
    
    if (tCelLen>0 && tDrobLen<1)
    {
        if (sign==-1) for (i=0, j=1; i<=tCelLen, j<=s; i++, j++) {cel[i]=str[j]; cel[i+1]='\0';}
        else for (i=0; i<=s; i++) {cel[i]=str[i]; cel[i+1]='\0';}
        cout<<cel;
    }
    

}

Имеятся и деструктор:
Код

~BigInt()
    {
        delete [] cel;
        delete [] drob;
    }

Так вот при компиляции вылетает ошибка...где-то вообщем с памятью напортачил, никак не могу найти ошибку!!! помогите пожалуйста!!! заранее благодарен!!!
PM MAIL   Вверх
nikitao
Дата 7.4.2006, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


Профиль
Группа: Завсегдатай
Сообщений: 1206
Регистрация: 30.8.2005
Где: Спб

Репутация: 1
Всего: 26



kleks, какая ошибка?приведи весь класс целиком.Могу лишь предположить ,что класс деструктор удаляет невыделенную память,иными словами он должен выглядить так :
Код

~BigInt()    
    {    
       if(cel)
          delete [] cel;    
       if (drop)
          delete [] drob;    
    }



--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
kleks
Дата 7.4.2006, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.10.2005

Репутация: нет
Всего: нет



Цитата
приведи весь класс целиком

Код

class BigInt
{
private:
    unsigned char *cel;
    unsigned char *drob;
    int cellen;
    int droblen;
    int sign;
    int zposition;
    unsigned char nol;
public:
    ~BigInt()
    {
        if (cel)
            delete [] cel;
        if (drob)
            delete [] drob;
    }
    BigInt(char *str);
};

/************************************************************************************************/

BigInt::BigInt(char *str)
{
    nol=0;
    long i, j;
    int tCelLen, tDrobLen, s;
char* ZapyatPos=strchr (str, ',');
    s=strlen(str);
    if (ZapyatPos==NULL)
    {
        droblen=0;
        tDrobLen=0;
        zposition=-1;
    }
    else
    {
        tDrobLen=&str[s]-(ZapyatPos+1);
    }
    
        
    if (str[0]=='-')
    {
        if (ZapyatPos==NULL)
        {
            sign=-1;
            tCelLen=s-1;
        }
        else
        {
            sign=-1;
            tCelLen=ZapyatPos-str-1;
            zposition=tCelLen+1;
        }
    }
    else
    {
        if (ZapyatPos==NULL)
        {
            sign=1;
            tCelLen=s;
        }
        else
        {
            sign=1;
            tCelLen=ZapyatPos-str;
            zposition=tCelLen;
        }
    }
    
    if (tCelLen<0) tCelLen=0;
    if (tDrobLen<0) tDrobLen=0;

    
    cellen=tCelLen;
    cel= new unsigned char [cellen];
    memset(cel,0,cellen);
    
    droblen=tDrobLen;
    drob= new unsigned char[droblen];
    memset(drob,0,droblen);
    
    if (tCelLen>0 && tDrobLen>0)
    {
    
    if (sign==-1)
    {
        for (i=1; i<=tCelLen; i++) {cel[i-1]=str[i]; cel[i]='\0';}
        for (i=0, j=tCelLen+2; i<=tDrobLen-1, j<=s; i++, j++) {drob[i]=str[j];}
    }

    else  
    {
        for (i=0; i<=tCelLen-1; i++) {cel[i]=str[i]; cel[i+1]='\0';}
        for (i=0, j=tCelLen+1; i<=tDrobLen-1, j<=s; i++, j++) drob[i]=str[j];
    }
    
    cout<<cel;
    cout<<",";
    cout<<drob;
    }

    if (tCelLen==0 && tDrobLen>0)
    {
        if (sign==-1) for (i=0, j=2; i<=tDrobLen-1, j<=s; i++, j++) drob[i]=str[j];
        else for (i=0, j=1; i<=tDrobLen-1, j<=s; i++, j++) drob[i]=str[j];
        cout<<",";
        cout<<drob;
    }
    
    if (tCelLen>0 && tDrobLen<1)
    {
        if (sign==-1) for (i=0, j=1; i<=tCelLen, j<=s; i++, j++) {cel[i]=str[j]; cel[i+1]='\0';}
        else for (i=0; i<=s; i++) {cel[i]=str[i]; cel[i+1]='\0';}
        cout<<cel;
    }
    

}

А ошибка следующая: HEAP CORRUPTIPN DETECTED: after Normal block (#62) at 0x003327d8 CRT
detected that the application wrote to memory after end of heap buffer

PM MAIL   Вверх
maxim1000
Дата 7.4.2006, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



Цитата(nikitao @ 7.4.2006, 21:31 Найти цитируемый пост)
if(cel)
          delete [] cel

с точки зрения стандарта удаление 0-вого указателя - обычное дело, и не приводит ни к каким проблемам
MSVC этому соответствует, BC++Builder, по-моему, тоже (не помню точно, но вроде проверял)


--------------------
qqq
PM WWW   Вверх
Daevaorn
Дата 8.4.2006, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



kleks,
У тебя в классе BigInt есть два указателя, но нет конструктора копирования и оператора присваивания, что может повлечь за собой такие ошибки. Получается, что какой-то экземпляр класса пытается освободить указатель, который уже освобожден другим экземпляром.
PM MAIL WWW   Вверх
MAKCim
Дата 8.4.2006, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



а не проще так
Код

class BigInt
{
private:
    typeef vector<char> _Chars;
    bool minus_flag_;
    _Chars int_tail_, float_tail_;
public:
    class null_string {};

    BigInt(const char* number_)
    {
        assert<null_string>(number_);
        if (*number_==ct_minus)
        {
            minus_flag_=true;
            number_++;
        }
        else minus_flag_=false;
        while (*number_ && *number!=ct_devider) int_tail_.push_back(*number_++);
        if (*number) number++;
        while (*number_) float_tail_.push_back(*number++);
    }
};



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
kleks
Дата 8.4.2006, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.10.2005

Репутация: нет
Всего: нет



Цитата

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

Тоесть написание:
Код

BigInt& operator=(const BigInt&);
BigInt (const BigInt& Copy);

должно помочь...попробую конечно, но разве,действительно, в этом проблема?!
PM MAIL   Вверх
MAKCim
Дата 9.4.2006, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

должно помочь...попробую конечно, но разве,действительно, в этом проблема?!

если идет работа с памятью напрямую (выделение и т д), и не переопределены конструктор копий и оператор присваивания, то да
не хочешь мучаться - используй vector, list ...(мой пример выше)


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
kleks
Дата 9.4.2006, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.10.2005

Репутация: нет
Всего: нет



MAKCim,
Спасибо огромное, но всё таки хочется со своим примером разобраться, а отсюда такой вопрос:
Код

char *a="2342342";
memset (a,0,3);
.
.

Почему в таком виде ф-ия memset() не работает?!
И еще, ели есть строка видa char *a="324234234"; каким образом можно освободить память занимаемую этой строкой используя функция delete???
заранее благодарен...

PM MAIL   Вверх
MAKCim
Дата 9.4.2006, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Почему в таком виде ф-ия memset() не работает?!

потому что a указывает на readonly строку (нельзя писАть)
память для не выделяется автоматически (сама строка находится в области константных данных)
освобождать эту память вручную не надо


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
kleks
Дата 9.4.2006, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.10.2005

Репутация: нет
Всего: нет



У меня тут вопрос такого плана: может кто-нибудь писал класс для работы с длинными числами...или возможно где-то, можно скачать соответствующие библиотеки...подскажите пожалуйста?! smile
PM MAIL   Вверх
MAKCim
Дата 10.4.2006, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

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

в нете полно
google


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
kleks
Дата 21.4.2006, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.10.2005

Репутация: нет
Всего: нет



Лазил в интернете и как раз нашёл неплохой класс для работы с длинными числами smile Только вот воспользоваться им так и не получается - при компиляции выдаёт 3 каких-то непонятных ошибки (компилятор VS 6.0), ссылку найти так и не смог, поэтому выкладываю сам файл:
Код

// LNum.h: interface for the CLNum class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_LNUM_H__6C7DF4A7_515D_11D5_AC10_EBC1DD062A0B__INCLUDED_)
#define AFX_LNUM_H__6C7DF4A7_515D_11D5_AC10_EBC1DD062A0B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "string.h"
#include <iostream>
#define DefCelSize  10
#define DefDrobSize 10
#define DefTochnost 10
#define ITNUM 8
class CLNum  
{
ostream& operator<<(ostream& s,CLNum& a);
friend CLNum sqrt(CLNum& a);
//friend CLNum operator+(CLNum& a, CLNum& b);
//friend CLNum operator-(CLNum& a, CLNum& b);
public:
    CLNum();//пустой конструктор;
    CLNum(unsigned int ,unsigned int,int);//Целая и дробная части
    CLNum(long);//Получаем экземпляр класса из переменной типа long
    CLNum(char in);
    CLNum(char* in);
    CLNum(const int);
    CLNum& operator=(const CLNum&);
    CLNum(const CLNum& Copy);
    virtual ~CLNum();
    struct Error//это исключение, которое мы будем бросать при ошибках, например в конструктор передано значание строки "12ф32".
    {
        const char* p;
        Error(const char* q){p=q;}
    };
    struct DivZero//деление на ноль
    {
    };
    //операторы

    unsigned char& operator[](const int index);// возвращает элемент(цифру) данного числа. Цифры после запятой имеют отрицательный индекс.
                                               //[0]-первая после запятой цифра целой части
    bool operator==(CLNum& b);
    bool operator!=(CLNum& b);
    bool operator<(CLNum& b);
    bool operator<=(CLNum &b);
    bool operator>(CLNum& b);
    bool operator>=(CLNum& b);
    CLNum operator-();// Унарный минус
    CLNum& operator<<(const int count);//Сдвигаем влево на count знаков
    CLNum& operator>>(const int count);//Сдвигаем вправо на count знаков
    CLNum& operator+=(CLNum& b);
    CLNum& operator-=(CLNum& b);
    CLNum& operator*=(CLNum& b);
    CLNum& operator/=(CLNum& b);
    void TrimCel(); //Убирает слева ненужные нули. Освобождает память, занимаемую этими нулями
    void TrimDrob();//Убирает ненужные нули справа.
    int GetTochnost();
    void SetTochnost(const int a);
    int GetCellen(){return cellen;}
    int GetDroblen(){return droblen;}
    char GetSign(){return sign;}
    void SetVal(char* in);
    void SetVal(const int in);
private:
    unsigned char *cel;// Целая часть
    unsigned char *drob;//Дробная часть
    /*unsigned*/ int cellen;// Длина целой части длинного числа
    /*unsigned*/ int droblen;//Длина дробной части
//    int zposition;//позиция запятой
    char sign;//Знак числа
    unsigned char nol;//ссылку на этот элемент будет возвращаеть op[] если элемента с требуемым индексом не сущ.
    int tochnost;
};
ostream& operator<<(ostream& s,const CLNum& a);
CLNum operator+(CLNum& a, CLNum& b);
CLNum operator-(CLNum& a, CLNum& b);
CLNum operator+(const int a, CLNum& b);
CLNum operator*(CLNum& a, CLNum& b);
CLNum operator/(CLNum& a, CLNum& b); 
CLNum operator*(const int a,CLNum& b);
//CLNum sqrt(CLNum& a);
#endif // !defined(AFX_LNUM_H__6C7DF4A7_515D_11D5_AC10_EBC1DD062A0B__INCLUDED_)


Так выглядит h-файл..., cpp-файл вложен (хотел выложить сразу rar-файл, но форум выдавал ошибку smile ) 

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  LNum.cpp 27,32 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1094 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.