![]() |
|
Модераторы: bsa |
![]()
|
|
| Курсант |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: 1 Всего: 4 |
Трабла такова. При освобождении памяти, выделенной под данные-члены, появляется ошибка "CRT detected that the application wrote to memory after end of heap buffer".. И так по количеству данных-членов (строк)... Сколько строк столько и сообщений об ошибке.
Сразу скажу - убрать освобождение памяти в деструкторе объекта я пробовал, и ошибка пропадала, но мне непонятна сама причина ошибки - вроде бы все должно работать именно так, потому что так правильнее... Собственно история Написал модуль класса WordCountList, для подсчета слов. У него есть метод void Put (char* слово), и в зависимости от того есть такое слово в списке или нет, объект либо увеличивает счетчик для данного слова, либо создает новую запись с единичным счетчиком. Собственно, реализация класса:
Этот объект используется в программе таким образом:
Собственно все... Спасибо |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
весь код не смотрел, но отсутсвие копи-конструктора наводит на подозрения. И если где то в программе есть передача подобного объекта по значению, то
оба объект (оригинал и копия) будут указывать на один и тот же выделенный блок памяти (itsString), а следовательно при удалении одного из этих объектов, указатель(itsString), становится не валидным, что ведет к ошибке при любом его дальнейшем использовании, в том числе и повторное delete[] itsString. |
|||
|
||||
| gosn1ck |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 103 Регистрация: 18.4.2009 Репутация: 1 Всего: 1 |
простите, что вмешиваюсь, а что такое копи-конструктор ?))
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
конструктор, который формирует объект по образу. Используется в частности при передачи аргумента по значению, для создания копии объекта. Это сообщение отредактировал(а) mes - 4.6.2009, 13:44 |
|||
|
||||
| azesmcar |
|
||||||||||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
copy constructor, он же копирующий конструктор - это конструктор который принимает в качестве аргумента ссылку или константную ссылку на обьект своего типа.
вызывается эта прелесть в этом случае
еще он вызывается при других видах копирования, например при передаче параметра функции по значению.
для вызова копи конструктора в данном случае существует список инициализации
если его не написать, компилятор сгенерирует его за вас, и сгенерированный копи-конструктор будет примерно иметь следующий вид
что касается константности аргумента копи конструктора - сгенерированный конструктор будет получать константную ссылку, если копи-конструкторы всех членов класса принимают константную ссылку, и неконстантный соответственно если один из членов имеет неконстантный аргумент копи-конструктора. Теперь насчет того, когда имеет смысл его писать. Писать его нужно если написанный вами копирующий конструктор будет отличаться от сгенерированного. Если у вас в классе есть динамическое выделение памяти, это первый признак того, что пора задуматся о необходимости написания/закрытия копирующего конструктора. Если копирование обьекта не предполагается то его можно закрыть и не реализовывать.
надеюсь ничего важного не упустил думаю достаточно информации на первое время Это сообщение отредактировал(а) azesmcar - 9.4.2010, 08:24 |
||||||||||||
|
|||||||||||||
| Курсант |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: 1 Всего: 4 |
В том то и дело что по значению я не передавал объекты - все завязано на указателях... Дубль два
Ошибка пропала после того как в конструкторе счетчика объявляем массив символов на единицу больший strlen(аргумента) ... То есть конфликтовали у меня два участка кода: этот
и этот:
Получается что itsString[len]='\0' в первом участке обращается за пределы массива строк... но вот незадача... Ошибки доступа к памяти не возникает - просто затирается видимо что-то, либо промежутки между данными специально оставлены, не суть важно... Важно то, что если убрать delete[] itsString, либо если правильно организовать работу с массивом (то есть объявить его на единицу больше), то ошибки не появляется... Отсюда вопрос... Ошибка возникает из за особенностей учета памяти, то есть delete[] itsString пытается удалить не только тот участок памяти, который был выделен изначально, но и тот байт за пределами массива, в который я писал когда неправильно организовал работу с массивом... Вопрос - как такое вообще возможно? ИМХО это нереально, но опыт подтверждает. приложение А: исправленный конструктор
|
||||||
|
|||||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Курсант
strlen возвращает вам не размер массива а длину строки. Не забывайте про завершающий \0 Добавлено @ 14:37 Курсант немного опоздал с ответом Это сообщение отредактировал(а) azesmcar - 4.6.2009, 21:01 |
|||
|
||||
| Курсант |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: 1 Всего: 4 |
Спасибо
|
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Он то удаляет то, что ему принадлежит, а вот вы своим '\0' в конце строки стерли данные, которые вам не принадлежали. А принадлежали они менеджеру динамической памяти, о чем он и сказал, когда появилась такая возможность (на delete)
Когда вы заказываете память определенного размера, то менеджер памяти возвращает вам указатель на выделенную память, при этом гарантируется, что вы можете свободно обращаться через него в пределах того размера, который указали при заказе памяти. ЗА ПРЕДЕЛЫ этого размера вы обращаться НЕ ИМЕЕТЕ ПРАВА вообще. Последствия будут непредсказуемые |
||||
|
|||||
| Курсант |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 338 Регистрация: 21.2.2009 Где: Балашиха или Воро неж Репутация: 1 Всего: 4 |
Да, Вы правы, только что попробовал освободить два раза один указатель - эффекты возникают более красочные |
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |