![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
NightGoblin |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1021 Регистрация: 24.11.2002 Где: 127.0.0.1 Репутация: нет Всего: 11 |
Извините, что вклиниваюсь с подобными ламерскими вопросами, но, чувствую, из книги я еще долго буду выуживать, что же у меня неправильно
![]() Ситуация такова: есть строковый класс rstring (распространенный учебный пример для начинающих), содержащий два приватных элемента: char* (без нуль-терминатора) и unsigned int, описывающий его длину. При нем определены операторы сравнения, присвоения и конкатенации. В последних и есть проблема. Есть простая тестовая программка, где объявляются три объекта этого класса: два содержат разные строки, третий служит для получения результата конкатенации. Вроде бы все работает, но не работает: после распечатки сообщения, при завершении выдает Segmentation fault. Вроде понятно, что должна быть ошибка с выделением/освобождением памяти, но вот где точно - не знаю. Удалось выяснить, что проблема в операторе "+" (скорее всего), поскольку без него все работает нормально. Вот исходный код оператора:
Кстати, аналогичный opertator+ (rstring, char*) вообще возвращает пустую строку... Не подскажете, в чем может быть проблема? -------------------- Kernel panic: /dev/null overflow! GCS/IT/MU/O d-@ s: a- C++$>++++$ ULSB(+++) P+++ L+++>++++ !E W++(-) N o? K w-- O? M>+ V? PS+ PE Y+ PGP+>+++ t- 5 X+ R- !tv b+ DI+ D+ G e++ h--- r++ y? B4F1 54B6 8738 26CD 5125 0581 B923 9273 FE59 1981 |
|||
|
||||
Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: 8 Всего: 12 |
В глаза сразу это бросилось, в остальной код я не вглядывался...
Тут к str присваивается указатель ts, а потом мы удаляем все, на что этот указатель указывал. И в результате возвращаем нечто... -------------------- "Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande |
|||
|
||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
![]() ![]() -------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
Baa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2639 Регистрация: 12.4.2002 Где: Москва Репутация: 8 Всего: 12 |
На самом деле, возврат указателя - штука очень удобная... но вот надо быть полностью увереным в добросовестности других функций, дабы они за собой почистили память.
-------------------- "Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande |
|||
|
||||
Step |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5151 Регистрация: 26.9.2002 Где: дурдом.UA Репутация: 5 Всего: 25 |
Это конецно интересно, только вот возникает проблема когда два раза подряд эту функцию вызываеш. -------------------- - Дурак учится на своих ошибках, умный на чужих. - умные учатся у дураков |
|||
|
||||
Fantasist |
|
||||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Смотри внимательнее. Переменныя str имеет тип rstring, а значит тут будет вызван конструктор rstring([const] char*), который скорее всего произведет копирование. Вообще, на первый взгляд ошибок не видно. Походи деббагером - все проявиться. -------------------- Волны гасят ветер... |
||||
|
|||||
Fantasist |
|
||||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Вообще-то по-моему, лучше реализовать это примерно так:
Понятнее и эффективнее. Можно, конечно, еще лучше, но это уже надо класс редактировать. getbuffer() должна возвращать внутренний указатель на char* и возможно следует сделать ее приватной. Функции getbuffer() и getlenght() (а можно и SetLenght()) нужно сделать inline. Да! Совсем забыл. Убедись, что у тебя правильно определен конструктор копий. -------------------- Волны гасят ветер... |
||||
|
|||||
dim |
|
|||
Unregistered |
Еще вылетать может быть если либо не инициализируется член содержащий длину или же он не меняется при изменении члена содержащего собсвенно строку, например в том же констукторе копирования. Вообщем все места в классе с ним связанные лучше проверить.
|
|||
|
||||
DrMasik |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 35 Регистрация: 13.12.2002 Репутация: нет Всего: нет |
1. rstring str = ts;//Посмотри внимательно!!!!
2. delete [] ts; 3. return str; В строке 1, ты присваиваешь переменной "занчение" которое содержится в ts! таким образом, если ты вызываешь после строки 2, что ты и сделал в строке 3, то ты обращаешся туда. чего уже нет! ![]() |
|||
|
||||
NightGoblin |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1021 Регистрация: 24.11.2002 Где: 127.0.0.1 Репутация: нет Всего: 11 |
(а также 2 Baa) Да, прошу прощения, забыл сказать, что конструктор rstring (const char*) для rstring действительно определен так, что char* копируется в rstring, а не просто указатель на него присваивается массиву char в rstring. Иначе бы вообще не работало... -------------------- Kernel panic: /dev/null overflow! GCS/IT/MU/O d-@ s: a- C++$>++++$ ULSB(+++) P+++ L+++>++++ !E W++(-) N o? K w-- O? M>+ V? PS+ PE Y+ PGP+>+++ t- 5 X+ R- !tv b+ DI+ D+ G e++ h--- r++ y? B4F1 54B6 8738 26CD 5125 0581 B923 9273 FE59 1981 |
|||
|
||||
NightGoblin |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1021 Регистрация: 24.11.2002 Где: 127.0.0.1 Репутация: нет Всего: 11 |
Хм, спасибо, надо попробовать ![]() -------------------- Kernel panic: /dev/null overflow! GCS/IT/MU/O d-@ s: a- C++$>++++$ ULSB(+++) P+++ L+++>++++ !E W++(-) N o? K w-- O? M>+ V? PS+ PE Y+ PGP+>+++ t- 5 X+ R- !tv b+ DI+ D+ G e++ h--- r++ y? B4F1 54B6 8738 26CD 5125 0581 B923 9273 FE59 1981 |
|||
|
||||
NightGoblin |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1021 Регистрация: 24.11.2002 Где: 127.0.0.1 Репутация: нет Всего: 11 |
2Fantasist:
Короче, говоря, спасибо за улучшенную реализацию. Однако, при переделке обнаружилась некая странная вещь: проблема вроде как даже и не в "+": если это выражение поставить в конструктор (rstring c = a + b;), то все работает без всяких Segmentation fault'ов, даже со старой функцией оператора. С другой стороны, если написать просто c = a, все выполнится опять же гладко. И только когда объекту присваивается результат конкатенации, начинаются чудеса... В общем, будем копать ![]() -------------------- Kernel panic: /dev/null overflow! GCS/IT/MU/O d-@ s: a- C++$>++++$ ULSB(+++) P+++ L+++>++++ !E W++(-) N o? K w-- O? M>+ V? PS+ PE Y+ PGP+>+++ t- 5 X+ R- !tv b+ DI+ D+ G e++ h--- r++ y? B4F1 54B6 8738 26CD 5125 0581 B923 9273 FE59 1981 |
|||
|
||||
NightGoblin |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1021 Регистрация: 24.11.2002 Где: 127.0.0.1 Репутация: нет Всего: 11 |
Прошу прощения за флуд. ))
Проблема выяснена: стоило в операторе присваивания (rstring::operator=) поставить аргументом rstring вместо rstring*, все заработало как надо ![]() ![]() ну и программер из меня однако ![]() ![]() -------------------- Kernel panic: /dev/null overflow! GCS/IT/MU/O d-@ s: a- C++$>++++$ ULSB(+++) P+++ L+++>++++ !E W++(-) N o? K w-- O? M>+ V? PS+ PE Y+ PGP+>+++ t- 5 X+ R- !tv b+ DI+ D+ G e++ h--- r++ y? B4F1 54B6 8738 26CD 5125 0581 B923 9273 FE59 1981 |
|||
|
||||
Fantasist |
|
|||
![]() Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
А это с самого начало было понятно. ![]() Я же сказал, что в том коде ошибок не видно, и предлагал дебаггером походить. -------------------- Волны гасят ветер... |
|||
|
||||
NightGoblin |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1021 Регистрация: 24.11.2002 Где: 127.0.0.1 Репутация: нет Всего: 11 |
Кстати, при передаче аргументов rstring& rstring::operator= (rstring); в виде rstring, а не rstring* использует указатели или так и пихает всю структуру в стек?...
-------------------- Kernel panic: /dev/null overflow! GCS/IT/MU/O d-@ s: a- C++$>++++$ ULSB(+++) P+++ L+++>++++ !E W++(-) N o? K w-- O? M>+ V? PS+ PE Y+ PGP+>+++ t- 5 X+ R- !tv b+ DI+ D+ G e++ h--- r++ y? B4F1 54B6 8738 26CD 5125 0581 B923 9273 FE59 1981 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |