Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

(c++) выделение памяти

14K
07 декабря 2007 года
v0lkan0
32 / / 02.03.2007
Код:
class rusStr
{
    char *stroka;
public:

    rusStr(char *s = "")
    {
        stroka=new char;
        strcpy(stroka,filter(s));
    }

    ~rusStr() {delete stroka;}
   
    rusStr operator+ (char* s)
    {
        strcat(stroka, filter(s));
        return *this;
    }

    rusStr operator+ (rusStr str)
    {
        strcat(stroka, str.stroka);
        return *this;
    }

    char* filter(char* s)
    {
        char* str;
        str=new char;
        //фильтруеться и результат записывается в str;
        return str;
    }
};


вопрос: нужно ли мне самому удалять str, и если да, то ГДЕ? удаление в деструкторе, конструкторе и в любой фу-ции вызывающей filter(); приводит к ошибке!

и еще, при помощи какой функции можно все содержимое текстового файла содрать в char* s; если можно то пожалуйста на примере.
350
07 декабря 2007 года
cheburator
589 / / 01.06.2006
Жуть какая.
1) В двух местах встретил new char. Ты уверен, что тебе нужно выделить место под ОДИН символ? Определи требуемый размер, затем выдели new char [ТребуемыйРазмер]. Не забудь, что требуется место и под закрывающий нуль. Насчет strcat в операторе "+" тоже замечание - stroka не рассчитана на столько символов, надо довыделять память.
2) Метод char *filter (char *) не использует данных класса - лучше сделать его статическим.

Теперь собственно по вопросу удаления str. Насколько я понял, речь идет о char *str в методе filter. Во-первых, не удаление приводит к ошибке, а кривое выделение (см. выше, пункт 1). Во-вторых, удалять надо сразу, как выделенное место больше не нужно (в данном случае, в конструкторе сразу после вызова filter). В-третьих, я бы сделал так:
 
Код:
rusStr(char *s = "")
{
stroka=filter(s);
}

А код освобождения уже реализован в деструкторе. По деструктору единственное замечание - пиши delete[] stroka

По второму вопросу создавай отдельную тему.
320
08 декабря 2007 года
m_Valery
1.0K / / 08.01.2007
Наверное в каждой книге по С++ рассматривается собственный класс строк,где и можно посмотреть код.Вот что пишет по этому поводу всемирный авторитет и знаток С++ Скотт Майерс.
...я использую как обьекты String,так и обьекты string,но для разных целей.(Заметьте,что первое название
пишется с большой буквы,а второе с маленькой.)Если мне просто нужно использовать строку,а ее реализация не важна,то я использую тип string,являющийся частью стандартной библиотеки С++.Этого правила
следует придерживаться и вам.Однако зачастую мне необходимо показать,как работает С++; в таких случаях требуется некоторый код реализации.Тогда я использую нестандартный класс String.Как программист, вы должны всегда,когда вам необходим обьект-строка использовать стандартный тип string;время создания своих собственных классов строк,прежде являющегося неотьемлемой частью ритуала посвящения в С++, уже миновало.Тем не менее необходимо разбираться в вопросах.связанных с созданием классов,подобных string. Для этой и только для этой цели удобно использовать класс String.Что же касается простых строк типа char * , то без веских причин нет необходимости в использовании подобных атавизмов.Хорошо реализованный тип string сегодня предпочтительнее типа char * рпрактически с любой точки зрения,в том числе и с соображений эффективности.


Кроме Скотта Майерса собственный класс строк(в той или иной степени подробности) рассматривается в книгах Бьерна Страуструпа,Герба Саттера,Стэнли Липпмана,Джима Коплиена и других.Где скачать все эти книги - смотри в Полезных ссылках раздела Студентам.Один из многочисленных примеров собственного класса String.

Код:
#include <iostream>
using namespace std;
class String                    //  Объявление строкового класса
{
   private:
       char* S;                  //  Строка
       size_t len;                  //  Длина строки
   public:
       String();                 //  Конструктор по умолчанию
       String(const char* s);    //  Перегруженный конструктор
       String(const String& s);  //  Конструктор копирования
       ~String() { delete [] S; }//  Деструктор      
        //  Дружественные функции
        //  Перегрузка бинарного оператора
        //  Функция реализует сцепление строк
        friend String operator+(const String&, const String&);    
        //  Перегрузка бинарного оператора
        //  Функция реализует пересечение строк
        friend String operator*(const String&, const String&);
        //  Перегрузка унарного оператора
        //  Функция реализует поиск уникальных элементов строки
        friend String operator!(const String&);        
        //  Перегрузка бинарного оператора
        //  Функция реализует ввод объектов класса с клавиатуры
        friend istream& operator>>(istream&, String&);
        //  Перегрузка бинарного оператора
        //  Функция реализует вывод объектов класса на экран
        friend ostream& operator<<(ostream&, const String&);
        String& operator=(const String&);
        //  Перегрузка типа
        //  Функция реализует преобразование объекта класса к типу char*
        operator char*() { return S; }
        //  Функция сортировки        
        void Sort(String s[], int n);  
        //  Функция возвращает длину строки
        size_t GetLen() { return len; }  
};
String::String()
{
    S = NULL;          //  начальная инициализация
    len = 0;
}
String::String(const char* s)
{
    len = strlen(s);
    S = new char[len + 1];
    //  Инициализация строкой, переданной пользователем
    strcpy(S, s);            
}
String::String(const String& s)
{
    len = s.len;
    S = new char[len + 1];   //  Безопасное копирование
    strcpy(S, s.S);
}
void String::Sort(String s[], int n)
{
    //  Сортировка строк
    bool flag = true;
    String temp;
    for(int j = 1; ; j++)  
    {
        for(int i = 0; i < n - j; i++)
            if(strcmp(s, s[i + 1]) > 0)
            //  Происходит обращение к
            //  строкам напрямую, благодаря
            //  неявному вызову функции класса string
            //  operator char*()
            {                            
                temp = s;       //  Вызов функции operator=(s)
                s = s[i + 1];   //  Вызов функции operator=(s[i + 1])
                s[i + 1] = temp;   //  Вызов функции operator=(temp)

                flag = false;
            }
        if(flag)
            break;
        flag = true;
    }
}
String operator+(const String &str1, const String &str2)
{                               //  Функция сцепления строк
    String s;                   //  Создание временного объекта
    s.len = str1.len + str2.len;//  Вычисление новой длины строки
    s.S = new char[s.len + 1];  //  Выделение памяти под новую строку
    strcpy(s.S, str1.S);        //  Инициализация первой части строки
    strcat(s.S, str2.S);        //  Инициализация второй части строки
    return s;                   //  Возврат нового объекта
}
String operator*(const String &str1, const String &str2)
{                               //  Функция сцепления строк
    String s;                   //  Создание временного объекта
    s.len = (str1.len > str2.len)? str1.len : str2.len;
                                //  Вычисление новой длины строки
    s.S = new char[s.len + 1];  //  Выделение памяти под новую строку

    size_t s1 = str1.len;          //  Длина первой строки
    size_t s2 = str2.len;          //  Длина второй строки
    int k = 0;                  //  Индекс результирующей строки
    for(size_t i = 0; i < s1; i++)
        for(size_t j = 0; j < s2; j++)
            if(str1.S == str2.S[j])
            {
                s.S[k] = str1.S;
                                //  Помещаем найденный символ,
                k++;            //  увеличиваем индекс,
                break;          //  выходим из цикла
            }
    s.S[k] = 0;                 //  Вставляем завершающий символ \0
    s.len = strlen(s.S);
    if(s.len > 1){
        return !s;              //  Возврат нового объекта
    }                          //  Вызов функции operator !(s)
    return s;
}
String operator!(const String& str)
{                               //  Функция нахождения уникальных
                                //  элементов строк
    String s;
    size_t l = s.len = str.len;
    s.S = new char[s.len + 1];
    s.S[0] = str.S[0];          //  Копирование первого символа
    for(size_t n = 1; n < l; n++)
        s.S[n] = 0;             //  Обнуление остальных элементов
    int k = 1;                  //  Индекс для новой строки
    bool flag = true;
    for(size_t i = 1; i < l; i++)  //  Поиск уникальных элементов
    {
        for(size_t j = 0; j < l; j++)
            if(s.S[j] == 0)
                break;
            else if(s.S[j] == str.S)
            {
                flag = false;
                break;
            }
        if(flag)
        {
            s.S[k] = str.S;  //  Добавление уникального символа
                                //  в строку
            k++;                //  Увеличение индекса
        }
        flag = true;
    }
    s.S[k] = 0;
    return s;                   //  Возврат полученной строки
}
istream& operator>>(istream& is, String& str)
{
    const int N = 65536;
    // Временный массив для многострочного ввода
    char temp[N] = {0};
    size_t Length = 0, //длина последней введенной строки,
    Total = 0; //общая длина ввода;
    // ввод продолжается до ввода пустой строки
    do
    {
        // запрашиваем строку
        is.getline(temp + Total, N - Total);
        // замеряем длину введенной строки
        Length = strlen(temp + Total);
        // если строка пуста
        if(Length == 0)
            break;
        // увеличиваем общую длину
        Total += Length + 1/* 1 - это \n */;
        temp[Total - 1] = '\n';    
    } while(Total < N);
    // Убираем последний Enter
    temp[Total - 1] = 0;
    // вызываем конструктор преобразования и
    // перегруженный оператор присваивания
    str = temp;
    return is;
}
ostream& operator<<(ostream& os, const String& str)
{
    os << str.S;                //  Вывод строки
    return os;                  //  Возврат объекта вывода
}
//  Функция, реализующая безопасное присваивание
String& String::operator=(const String &str)
{                              
    if(this == &str)
        return *this;
    if(len != str.len || len == 0)
    {
        delete [] S;            //  Удаление старой строки
        len = str.len;          //  Вычисление новой длины строки
        S = new char[len + 1];  //  Выделение памяти под новую строку
    }
    strcpy(S, str.S);           //  Инициализация строки
    return *this;               //  Возврат ссылки на "самого себя"
                                //  Благодаря этому возможно многократное
                                //  присваивание объектов друг другу
                                //  например, string a, b, c; a = b = c;
}
int _tmain(int argc, _TCHAR* argv[])
{
    String a, b, c;
    cout << "Input the first part of string:\n";
    cin >> a;
    cout << "Input the second part of string:\n";
    cin >> b;
    c = a + "\n" + b + "\n";  
    cout << c;  //  Вывод результирующей строки
    return 0;
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог