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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
#1

Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок - C++

29.01.2016, 11:30. Просмотров 429. Ответов 20
Метки нет (Все метки)

Сделал класс, который ведет себя аналогично char*, но с возможностью сложения строк. Вроде все работает как надо, но есть ли какие-то подводные камни, утечки памяти? Может что-то сделано криво и можно поумнее? Дело в том, что на этот класс мне надо будет потом полностью полагаться и быть уверенным, что в нем нет ошибок. Вот код:

vstring.h
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
class vstring
    {
    private:
        char* Str;
        int length;
    public:
        vstring(char* str = 0);
        vstring(char s);
        vstring(vstring& str);
 
        ~vstring(){delete [] Str;}
 
        char operator[](int index);
 
        friend std::ostream& operator<<(std::ostream& out, vstring& str);
 
        vstring operator+(vstring& str);
        vstring operator+(char symbol);
        friend vstring operator+(char symbol, vstring& str);
 
        operator char*();
 
        vstring& operator=(char* s);
        vstring& operator=(vstring& str);
         };
vstring.cpp
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
vstring::vstring(char* str)
{
    if(str == 0)
    {
        Str = new char[1];
        length = 0;
        Str[0] = '\0';
        return;
    }
    for(length = 0; str[length] != '\0'; length++);
    Str = new char[length+1];
    Str[length] = '\0';
    for(int i(0); i < length; i++)
        Str[i] = str[i];
}
vstring::vstring(char s)
{
    Str = new char[2];
    length = 1;
    Str[1] = '\0';
    Str[0] = s;
}
 
vchar vstring::operator[](int index)
{
    return Str[index];
}
 
vstring::vstring(vstring& str)
{
    Str = new char [str.length+1];
 
    for(int i(0); i < str.length; i++)
        Str[i] = str[i];
    Str[str.length] = '\0';
    length = str.length;
}
 
std::ostream& operator<<(std::ostream& out, vstring& str)
{
    for(int i(0); i < str.length; i++)
        out << str[i];
    return out;
}
 
vstring operator+(char symbol, vstring& str)
{
    return vstring(symbol) + str;
}
 
vstring vstring::operator+(vstring& str)
{
    char* resStr = new char[length + str.length + 1];
 
    int i(0);
    for(; i < length; i++)
        resStr[i] = Str[i];
    for(; i < length + str.length; i++)
        resStr[i] = str[i-length]; 
    resStr[i] = '\0';
        
        vstring ret(resStr);
        delete [] resStr;
    return ret;
}
 
vstring vstring::operator+(char symbol)
{
    return *this + vstring(symbol);
}
 
vstring& vstring::operator=(char* s)
{
    delete [] Str;
 
    vstring str(s);
 
    Str = new char[str.length+1];
    for(int i(0); i < str.length; i++)
        Str[i] = str[i];
    Str[str.length] = '\0';
    length = str.length;
 
    return *this;
}
 
vstring& vstring::operator=(vstring& str)
{
    delete [] Str;
 
    Str = new char[str.length+1];
    for(int i(0); i < str.length; i++)
        Str[i] = str[i];
    Str[str.length] = '\0';
    length = str.length;
 
    return *this;
}
 
vstring::operator char*()
{
    char* str = new char[length+1];
    for(int i(0); i < length; i++)
        str[i] = Str[i];
    str[length] = '\0';
 
    return str;
}
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.01.2016, 11:30     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок
Посмотрите здесь:

C++ Проверьте код на наличие ошибок.
Начал писать прогу чтобы текст передвигался по экрану, я что то написал но у меня ошибок куча, подскажите пожалуйстаа :) C++
как проверить наличие утечек памяти в шаблоне? C++
Чтобы не было утечек памяти C++
Подключении механизма обнаружение утечек памяти C++
Подскажите программу для диагностики утечек памяти C++
Проверьте, на наличие ошибок C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Dimension
Dimension
555 / 436 / 135
Регистрация: 08.04.2014
Сообщений: 1,709
Завершенные тесты: 1
29.01.2016, 11:36     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #2
это все уже есть в string , зачем свои велосипед делать не понимаю
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
29.01.2016, 11:43  [ТС]     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #3
Dimension, это для школы, мы там только велосипеды и изобретаем.
Croessmah
Модератор
Эксперт CЭксперт С++
 Аватар для Croessmah
12508 / 7070 / 794
Регистрация: 27.09.2012
Сообщений: 17,454
Записей в блоге: 2
Завершенные тесты: 1
29.01.2016, 11:47     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
C++
1
2
3
4
vstring(vstring& str);
vstring& operator=(vstring& str);
vstring(char* str = 0);
vstring& operator=(char* s);
Почему параметры не const?
Разве нельзя копировать константную строку?
C++
1
friend std::ostream& operator<<(std::ostream& out, vstring& str);
а константные строки выводу не подлежат?
C++
1
int length;
почему знаковый тип?
Думаете, длина строки когда-то будет меньше нуля?
C++
1
char operator[](int index);
опять же, почему параметр имеет знаковый тип?
Почему возвращается не ссылка на символ, а копия?
C++
1
2
        vstring operator+(vstring& str);
        vstring operator+(char symbol);
Почему функции-члены не const?
Ну и ссылка в параметре тоже не const почему?
C++
1
operator char*();
хреновая идея. Возможны неявные касты,
а значит могут быть ошибки потом, которые черт поймаешь.
Лучше сделайте функцию-член c_str
C++
1
vchar vstring::operator[](int index)
что за vchar?
если это псевдоним,
то почему в объявлении char, а не vchar?
C++
1
for(length = 0; str[length] != '\0'; length++);
strlen и strcpy уже не в ходу?
C++
1
2
3
4
5
6
7
8
9
vstring::operator char*()
{
    char* str = new char[length+1];
    for(int i(0); i < length; i++)
        str[i] = Str[i];
    str[length] = '\0';
 
    return str;
}
Возвращаем копию строки, созданную динамически,
при этом заботу об освобождении возлагаем на клиента?
Фигня сразу. И спровоцирует чертову тучу утечек, т.к. неявный каст, см. выше.
C++
1
2
3
4
5
    Str = new char[str.length+1];
    for(int i(0); i < str.length; i++)
        Str[i] = str[i];
    Str[str.length] = '\0';
    length = str.length;
strcpy всё еще не в ходу.
Ну тогда хоть в свою функцию всё это дело оберните,
а то наплодили один и тот же код в тысячи местах. Не хорошо это

Вроде пока всё. Как исправите, приходите
CheshireCat
Эксперт С++
2910 / 1238 / 78
Регистрация: 27.05.2008
Сообщений: 3,321
29.01.2016, 11:49     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #5
Ну, написание своих велосипедов - лучший способ обучения.

Касательно самого кода: он у меня даже не компиляется (GCC 4.9), поэтому в дальнейшем анализе на "какие-то подводные камни, утечки памяти" не вижу смысла.
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
29.01.2016, 12:00  [ТС]     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #6
Croessmah, спасибо, буду исправлять, видите, все же надо иногда учиться на велосипедах.CheshireCat, думаю, это из-за того vchar вместо char (описка) в строке 24 vstring.cpp
CheshireCat
Эксперт С++
2910 / 1238 / 78
Регистрация: 27.05.2008
Сообщений: 3,321
29.01.2016, 12:06     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #7
Да, одна из ошибок была именно про vchar. Исправляй, как только код скомпиляется, погляжу более подробно и попробую написать несколько тестов, "ломающих" твой код.
Croessmah
Модератор
Эксперт CЭксперт С++
 Аватар для Croessmah
12508 / 7070 / 794
Регистрация: 27.09.2012
Сообщений: 17,454
Записей в блоге: 2
Завершенные тесты: 1
29.01.2016, 12:10     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #8
Цитата Сообщение от vaziliybober Посмотреть сообщение
Croessmah, спасибо, буду исправлять, видите, все же надо иногда учиться на велосипедах.
Я этого не отрицал. Сам писал.
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
29.01.2016, 21:30  [ТС]     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #9
Цитата Сообщение от CheshireCat Посмотреть сообщение
Исправляй, как только код скомпиляется, погляжу более подробно и попробую написать несколько тестов, "ломающих" твой код.
Если подключить <iostream> в vstring.h и "vstring.h" в vstring.cpp, то у меня на моем vs_2012 все компилится. Ну еще #pragma once можно на всякий. Мой косяк, не знаю, зачем я все это опустил.
Croessmah
Модератор
Эксперт CЭксперт С++
 Аватар для Croessmah
12508 / 7070 / 794
Регистрация: 27.09.2012
Сообщений: 17,454
Записей в блоге: 2
Завершенные тесты: 1
29.01.2016, 22:35     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #10
Цитата Сообщение от vaziliybober Посмотреть сообщение
Ну еще #pragma once можно на всякий
тогда можем попасть впросак,
если нет include guard'ов, т.к. прагмы не стандартны.
Также нет main'а, чтобы посмотреть как Вы всё это используете
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
29.01.2016, 23:06  [ТС]     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #11
Цитата Сообщение от Croessmah Посмотреть сообщение
Как исправите, приходите
ну вот вроде все.

vstring.h
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
#pragma once
#include <iostream>
 
class vstring
    {
    private:
        char* Str;
        unsigned int length;
 
        char* string_copy(const char* str);
        unsigned int string_length(const char* str);
    public:
        vstring(const char* str = 0);
        vstring(char s);
        vstring(const vstring& str);
 
        ~vstring(){delete [] Str;}
 
        char& operator[](unsigned int index) const;
 
        friend std::ostream& operator<<(std::ostream& out, const vstring& str);
 
        vstring operator+(const vstring& str) const;
        vstring operator+(char symbol) const;
        friend vstring operator+(char symbol, vstring& str);
 
        vstring& operator=(const char* s);
        vstring& operator=(const vstring& str);
 
        char* c_str();
    };
vstring.cpp
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
#include "vstring.h"
 
unsigned int vstring::string_length(const char* str)
{
    if(str == 0) return 0;
 
    unsigned int size;
    for(size = 0; str[size] != '\0'; size++);
    return size;
}
 
char* vstring::string_copy(const char* str)
{
    if(str == 0)
    {
        char* ret = new char[1];
        ret[0] = '\0';
        return ret;
    }
 
    char* ret = new char[string_length(str)+1];
    ret[string_length(str)] = '\0';
    for(int i(0); i < string_length(str); i++)
        ret[i] = str[i];
    return ret;
}
 
vstring::vstring(const char* str)
{
    Str = string_copy(str);
    length = string_length(str);
}
vstring::vstring(char s)
{
    Str = new char[2];
    length = 1;
    Str[1] = '\0';
    Str[0] = s;
}
 
char& vstring::operator[](unsigned int index) const
{
    return Str[index];
}
 
vstring::vstring(const vstring& str)
{
    Str = string_copy(str.Str);
    length = str.length;
}
 
std::ostream& operator<<(std::ostream& out, const vstring& str) 
{
    for(int i(0); i < str.length; i++)
        out << str[i];
    return out;
}
 
vstring operator+(char symbol, vstring& str)
{
    return vstring(symbol) + str;
}
 
vstring vstring::operator+(const vstring& str) const
{
    char* resStr = new char[length + str.length + 1];
 
    int i(0);
    for(; i < length; i++)
        resStr[i] = Str[i];
    for(; i < length + str.length; i++)
        resStr[i] = str[i-length]; 
    resStr[i] = '\0';
        
        vstring ret(resStr);
        delete [] resStr;
    return ret;
}
 
vstring vstring::operator+(char symbol) const
{
    return *this + vstring(symbol);
}
 
vstring& vstring::operator=(const char* s)
{
    delete [] Str;
    Str = string_copy(s);
    length = string_length(s);
 
    return *this;
}
 
vstring& vstring::operator=(const vstring& str)
{
    delete [] Str;
 
    Str = string_copy(str.Str);
    length = str.length;
 
    return *this;
}
 
char* vstring::c_str()
{
    return string_copy(Str);
}
Цитата Сообщение от Croessmah Посмотреть сообщение
Также нет main'а, чтобы посмотреть как Вы всё это используете
Да пока никак не использую. Как раз и обратился, чтобы потом использовать без сомнений в работе класса.

Добавлено через 4 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
тогда можем попасть впросак,
если нет include guard'ов, т.к. прагмы не стандартны.
ну пусть подключит стандартные include guardы вместо прагмы.
Croessmah
Модератор
Эксперт CЭксперт С++
 Аватар для Croessmah
12508 / 7070 / 794
Регистрация: 27.09.2012
Сообщений: 17,454
Записей в блоге: 2
Завершенные тесты: 1
29.01.2016, 23:12     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #12
Цитата Сообщение от vaziliybober Посмотреть сообщение
ну пусть подключит стандартные include guardы вместо прагмы.
Это Ваша задача - Вы же разработчик этого инструмента
C++
1
2
3
4
char* vstring::c_str()
{
    return string_copy(Str);
}
Зачем что-то копировать и выделять?
C++
1
2
3
4
const char* vstring::c_str() const //объявление подправить соответственно. Добавить noexcept по возможности.
{
    return Str ;
}
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
29.01.2016, 23:25  [ТС]     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #13
Цитата Сообщение от Croessmah Посмотреть сообщение
Зачем что-то копировать и выделять?
вот зачем
C++
1
2
3
4
vstring* str1 = new vstring("hello");
    char* str2 = str1->c_str();
    delete str1;
    cout << str2; // выдает крабозябры, т. к. удалился адрес Str (это если не копировать)
hoggy
5715 / 2306 / 417
Регистрация: 15.11.2014
Сообщений: 5,150
Завершенные тесты: 1
29.01.2016, 23:34     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #14
Цитата Сообщение от vaziliybober Посмотреть сообщение
char& vstring::operator[](unsigned int index) const
{
* * return Str[index];
}
у вас метод константный.
это значит, что он работает в режиме "только для чтения".
но при этом он возвращает мутабельный символ.

вы уверены, что это правильно:
изменять данные, которые возвращают константные методы?

ведь технически, получается, что таким образом
можно изменить символ константной от рождения строки,
и нарваться на UB

Добавлено через 4 минуты
Цитата Сообщение от vaziliybober Посмотреть сообщение
вот зачем

vstring* str1 = new vstring("hello");
* * char* str2 = str1->c_str();
* * delete str1;
* * cout << str2; // выдает крабозябры, т. к. удалился адрес Str (это если не копировать)
привет, говнокод и утечки памяти.
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
29.01.2016, 23:36  [ТС]     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #15
hoggy, я даже не знаю, что такое мутабельный символ. Никаких глубоких рассуждений у меня не было. Я просто не мог вызвать метод вот тут:
C++
1
2
3
4
5
6
std::ostream& operator<<(std::ostream& out, const vstring& str) 
{
    for(int i(0); i < str.length; i++)
        out << str[i]; // здесь
    return out;
}
Поэтому и приписал const.
Croessmah
Модератор
Эксперт CЭксперт С++
 Аватар для Croessmah
12508 / 7070 / 794
Регистрация: 27.09.2012
Сообщений: 17,454
Записей в блоге: 2
Завершенные тесты: 1
29.01.2016, 23:36     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #16
Цитата Сообщение от vaziliybober Посмотреть сообщение
вот зачем
а нефиг криво использовать.
hoggy
5715 / 2306 / 417
Регистрация: 15.11.2014
Сообщений: 5,150
Завершенные тесты: 1
29.01.2016, 23:39     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #17
Цитата Сообщение от vaziliybober Посмотреть сообщение
Поэтому и приписал const.
замените:
C++
1
2
char& vstring::operator[](unsigned int index) const
    { return Str[index]; }
на:

C++
1
2
3
4
5
const char& vstring::operator[](unsigned int index) const
    { return Str[index]; }
 
char& vstring::operator[](unsigned int index) 
    { return Str[index]; }
либо на:

C++
1
2
char vstring::operator[](unsigned int index) const
    { return Str[index]; }
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
29.01.2016, 23:47  [ТС]     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #18
hoggy, спасибо, исправил.

Цитата Сообщение от Croessmah Посмотреть сообщение
а нефиг криво использовать.
Но все же объясните 14-летнему чайнику-говнокодеру, как "ровно" использовать c_str(). Я ж просто хотел возможность преобразовывать в char*. Зачем мне в const char*?
hoggy
5715 / 2306 / 417
Регистрация: 15.11.2014
Сообщений: 5,150
Завершенные тесты: 1
29.01.2016, 23:52     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #19
Цитата Сообщение от vaziliybober Посмотреть сообщение
как "ровно" использовать c_str().
вот жеж:

Цитата Сообщение от Croessmah Посмотреть сообщение
const char* vstring::c_str() const //объявление подправить соответственно. Добавить noexcept по возможности.
{
* * return Str ;
}
если объект-строка уничтожен,
значит данные строки тоже уничтожены.
значит любые указатели выданные наружу более не действительные.

об этом нужно знать и помнить,
когда вы снаружи кэшируете данные во внешних указателях.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.01.2016, 00:03     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок
Еще ссылки по теме:

Проверьте блок схему на предмет ошибок C++
C++ Visual Studio 2015 Обнаружение утечек памяти
C++ Проверить код на наличие ошибок
Я написал программу шифрования и дешифрования,но много ошибок, исправьте пожалуйста C++
C++ Проверить программу на наличие ошибок

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

Или воспользуйтесь поиском по форуму:
vaziliybober
0 / 0 / 0
Регистрация: 02.01.2016
Сообщений: 25
30.01.2016, 00:03  [ТС]     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок #20
Цитата Сообщение от hoggy Посмотреть сообщение
об этом нужно знать и помнить,
когда вы снаружи кэшируете данные во внешних указателях.
ну а в конструкторах копирования мы ж без сомнений дублируем данные. Почему тогда в них нет таких заморочек?
Yandex
Объявления
30.01.2016, 00:03     Написал свой string. Проверьте код на наличие подводных камней, утечек памяти и других ошибок
Ответ Создать тему
Опции темы

Текущее время: 15:45. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru