![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
Очень странно вести себя стал
Допустим есть... char **test = new char*[MAX_TEST]; for(unsigned long i = 0; i <= MAX_TEST; i++) test[i] = new char[MAX_LONG_TEST+1]; Чтобы освободить память xочу испоьзовать... for(unsigned long i = 0; i <= MAX_TEST; i++) delete[] test[i]; delete[] test; Но программа при выполнении освобождения памяти почему-то сообщает о фатальной ошибке. ЗЫ нигде больше памятью test не управлял, поэтому грешить на удаление несуществующих членов не приходиться. Да к тому же вот это работает: delete[] test[0]; delete[] test[MAX_TEST]; delete[] test; Это сообщение отредактировал(а) En_t_end - 27.6.2005, 11:57 |
|||
|
||||
| comcon1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 838 Регистрация: 11.6.2005 Где: Москва ДАС-МГУ Репутация: 12 Всего: 17 |
Че-то я не втыкаю, почему ты удаляешь test[i] оператором delete[]. Ведь создаешь ты (char*) так:
ведь __string - не массив указателей, чтобы удалять ее delete[]. |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Было бы странно, если бы фатальной ошибки не было...
Вы выделяете MAX_TEST кусков памяти, а потом записываете в них MAX_TEST+1 указателей. Элемент с индексом MAX_TEST (test[MAX_TEST]) - незаконный. Программа валится на освобождении памяти, т.к. сама по себе запись в чужую память редко сразу приводит к фатальным последствиям. commom1 Формально, любой массив можно (нужно) удалять оператором delete[]. При этом компилятор вызывает деструктор для каждого элемента массива. Но в данном случае это, действительно, не обязательно, хотя вполне законно написано. А для массива указателей вызывать delete[] как раз бесполезно: delete для каждого элемента вызван не будет - это ответственность программиста - любишь вызывать new, люби и саночки возить... Или пользуйся smart-указателями. Это сообщение отредактировал(а) Earnest - 27.6.2005, 12:59 -------------------- ... |
|||
|
||||
| pablo |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 320 Регистрация: 12.2.2005 Где: Вильнюс, Литва Репутация: 4 Всего: 6 |
только что проверил твой код, он оказывается абсолютно рабочий, ищи ошибку в другом месте.
Вот код:
-------------------- Первый блин всегда похож на сферу, иногда бывает и куб. |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Да вы что, господа, какой рабочий! Валится или не валится - это уж как повезет. Причем везет - это когда валится сразу.
Но выделить MAX_TEST элементов, а заполнять MAX_TEST+1 - это, по-вашему, нормально? -------------------- ... |
|||
|
||||
| pablo |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 320 Регистрация: 12.2.2005 Где: Вильнюс, Литва Репутация: 4 Всего: 6 |
Извините не заметил, надо просто в циклах убрать снак равенства и всё будет в ажуре.
-------------------- Первый блин всегда похож на сферу, иногда бывает и куб. |
|||
|
||||
| En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
Earnest
Тогда покажи пример с char**, где бы память выделялась и освобождалась правильно. |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Pablo уже написал - замени в циклах "<=" на "<" и все будет правильно.
Цикл у тебя сколько раз выполняется? Правильно, MAX_TEST+1 раз. Последний элемент, который ты инициализируешь в цикле - это test[MAX_TEST]. Неважно, что ты туда пишешь - не имешь права, т.к. этого элемента нет. Это сообщение отредактировал(а) Earnest - 27.6.2005, 15:27 -------------------- ... |
|||
|
||||
| ManiaK |
|
||||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Earnest согласен. Жульничают
Насчёт:
По-хорошему всегда нужно удалять массив оператором delete[]. Даже в приведённом примере никто не гарантирует, что через какое-то время программу достанут и добавят какую-нибудь новую фичу, использующую переопределённые операторы new, new[], delete, delete[] в глобальной области. Насколько помню, могут быть немаленькие казусы и, главное, вы сначала порвёте все волосы у себя на голове и только потом поймёте, что вы сделали не так. |
||||
|
|||||
| En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
Earnest
delete[] test[MAX_TEST]; почему тогда это работает ? |
|||
|
||||
| ManiaK |
|
|||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
Насколько понимаю, удаляется массив указателей - и удаляется он верного размера. А вот если попытаться удалить элемент MAX+1 в нём - то будут проблемы, т.к. этого элемента не существует. |
|||
|
||||
| B2_Russia |
|
|||
![]() В доску свой :) ![]() ![]() Профиль Группа: Участник Сообщений: 344 Регистрация: 3.7.2003 Где: Тверь Репутация: нет Всего: 1 |
Попробуй так: for(unsigned long i = 0; i <= MAX_TEST; i++) delete[] test[i]; delete[] (char*)test; Короче может быть чтото с несоответствием типов |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
En_t_end
А это тебе кажется, что работает. Не повезло, значит. Имей в виду, что неправильный код рано или поздно стукнет. Причем в совершенно неожиданном месте. И искать такую ошибку ты можешь ох как долго. Почему сразу не валится, это еще и от компилятора зависит. Например, VC в отладочном режиме специально помечает память, выделенную new - а потом при освобождении проверяет, освобождаешь ли ты то, что выделил. Так что с этой точки зрения все, как кажется, нормально. Выделил указатель - освободил указатель. То, где хранится этот указатель, в данном случае не срабатывает - ты просто больше не трогаешь эту память. Вполне вероятно, что память сразу за массивом test выделяется для какого-то из массивов test[i]. Я думаю, если ты пройдешься по своей программе отладчиком и последишь за значениями переменных, увидишь много интересного. Скорее всего, содержимое ячейки test[MAX_TEST] изменяется во время одного из освобождений. А потом ты вызываешь для нее delete... Это сообщение отредактировал(а) Earnest - 27.6.2005, 15:46 -------------------- ... |
|||
|
||||
| En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
B2_Russia
Попробывал(предварительно в циклах убрал <= на <(это верно, просто я ступил |
|||
|
||||
| ManiaK |
|
|||
![]() Homo Sapience ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1145 Регистрация: 3.8.2004 Где: ИУ5-93 Репутация: 5 Всего: 29 |
А чему равна константа MAX_TEST если не секрет?
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |