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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.75
mansp
18 / 18 / 0
Регистрация: 07.11.2010
Сообщений: 136
#1

_BLOCK_TYPE_IS_VALID при вызове деструктора класса - C++

05.04.2011, 16:58. Просмотров 2489. Ответов 11
Метки нет (Все метки)

при вызове деструктора моего класса вылетает ошибка
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
конструкрор копирования создал и оператор = тоже ,
мой код:
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
class Animals
{
public:
    char *name;
    double weight;
    void print();
    virtual void input_informaton();
    char* Clear_Strng (char *s ,int size)
    {
        s = NULL;
        new_str(s, size);
        return s;
 
    }
    char* new_str (char *s, int size)
    {
        s = new char[size];
        return s;
    }
    Animals ();
    virtual ~Animals();
    Animals(const Animals& a);
    Animals& operator = (const Animals& a);
};
///////////////////////////////////////////////////////////////////////////////
void Animals::print()
{ 
    cout<<"\nname ";
    puts(name);
    cout<<"\nweight "<<weight;
}
Animals::Animals ()
{
    name = new char [20];
    name ="name";
    weight = 0.;
}
 
Animals::~Animals()
{
    delete name;
    weight = 0.;
 
}
Animals& Animals:: operator = (const Animals& a)
{
    weight = a.weight;
    strcpy(this->name,a.name);
    return *this;
    
}
Animals::Animals(const Animals& a)
{
    weight = a.weight;
    strcpy(this->name,a.name);
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
05.04.2011, 17:18     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #2
Мдя... Честно говоря, даже неохота перечислять ошибки. Советую сначала перечитать книгу по плюсам, начиная с... С начала, пожалуй, и кончая собственно самой ООП-составляющей языка. У вас куча ошибок в самых разных местах, начиная банально с того, что нельзя тупо присвоить указателю на char константную строку (name = "name"), и заканчивая непониманием работы с памятью (где что должно создаваться и удаляться). Уж извините за откровенность...
mansp
18 / 18 / 0
Регистрация: 07.11.2010
Сообщений: 136
05.04.2011, 18:47  [ТС]     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #3
хех)) чёт я затупил с конструктором копирования...

а почему нельзя напистать так
Код
name="name"
ведь я выделил памятьв конструкторе под мою строку name... да и работала у меня эта строчка нормально везде...

Добавлено через 24 минуты
хотя именно из за этой строчки у меня и не работал деструктор((
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
05.04.2011, 18:49     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #4
У вас есть указатель name. Вы выделяете для него память: name = new char [20];. Теперь он указывает на некоторую область памяти, выделенную в куче. На следующей строчке вы неявно создаёте константную строку "name" (в стеке) и тут же присваиваете адрес этой строки указателю name. Таким образом, ваша память, выделенная строкой раньше, теряется (она выделена, но адрес её безвозвратно потерян), а name теперь указывает на выделенную в стековой памяти константную строку. Затем, в деструкторе, вы пытаетесь применить delete к name. Но name указывает на область автоматической памяти (выделенной в стеке, объекты в которой автоматически удаляются по истечении времени жизни), и применять к этой памяти delete ни в коем случае нельзя, о чём и говорит выскочившее сообщение. Строку name = "name"; следует заменить на strcpy(name, "name"), в этом случае вы измените не просто указатель, а данные, на которые он указывает.
mansp
18 / 18 / 0
Регистрация: 07.11.2010
Сообщений: 136
07.04.2011, 17:16  [ТС]     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #5
заменил на стрцпу и переправил конструктор копирования но всё равно только после окончания программы появляетса эта ошибка... при вызове деструктора ошибок нет ...
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
07.04.2011, 17:21     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #6
Ошибка как раз появляется при вызове деструктора (потому как деструктор вызывается как раз когда программа завершается). И ошибка это говорит о проблемах с удалением памяти.
mansp
18 / 18 / 0
Регистрация: 07.11.2010
Сообщений: 136
07.04.2011, 17:45  [ТС]     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #7
вот что вылазит когда я использовалл маллок и фри вместо нью и делит
ОС Windows инициировала точку останова в lr 11.exe.

Это может быть вызвано повреждением кучи и указывает на ошибку в lr 11.exe или в одной из загруженных им DLL.

Возможной причиной так же может быть нажатие пользователем клавиши F12, когда фокус принадлежит lr 11.exe

Выведенное на экран окно содержит дополнительные данные для диагностики ошибки
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
07.04.2011, 17:53     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #8
mansp, вот рабочий (относительно нашего с вами обсуждения) вариант. Как видите, изменил только то, о чём говорил раньше.

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
#include <iostream>
#include <cstring>
 
using namespace std;
 
class Animals
{
public:
        char *name;
        double weight;
        void print();
        //virtual void input_informaton();
        char* Clear_Strng (char *s ,int size)
        {
                s = NULL;
                new_str(s, size);
                return s;
 
        }
        char* new_str (char *s, int size)
        {
                s = new char[size];
                return s;
        }
        Animals ();
        virtual ~Animals();
        Animals(const Animals& a);
        Animals& operator = (const Animals& a);
};
///////////////////////////////////////////////////////////////////////////////
void Animals::print()
{ 
        cout<<"\nname ";
        puts(name);
        cout<<"\nweight "<<weight;
}
Animals::Animals ()
{
        name = new char [20];
        strcpy(name, "name");
        weight = 0.;
}
 
Animals::~Animals()
{
        delete name;
        weight = 0.;
 
}
Animals& Animals:: operator = (const Animals& a)
{
        weight = a.weight;
        strcpy(this->name,a.name);
        return *this;
        
}
Animals::Animals(const Animals& a)
{
        weight = a.weight;
        strcpy(this->name,a.name);
}
 
int main()
{
    Animals horse;
 
    horse.print();
 
    return 0;
}
mansp
18 / 18 / 0
Регистрация: 07.11.2010
Сообщений: 136
07.04.2011, 18:00  [ТС]     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #9
извените, что я Вас уже замучал своей необразованостью
но почему если я добавляю в мейне строчку
Код
horse.~Animals();
вылетает снова эта ошибка?
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
07.04.2011, 18:07     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #10
Эм.. А за каким... вы вызываете деструктор явно? Деструкторы вызывается автоматически по окончании времени жизни объекта (при выходе из блока, в котором объект был создан), и вызывать деструктор самостоятельно нет никакой необходимости. В данном случае у вас возникает такая ситуация:
1. Вы вызывается деструктор явно
2. Деструктор вызывается повторно при выходе из main.
В пункте 2 оператор delete пытается освободить память, которая уже была освобождена в пункте 1, и применять delete к указателю на память, которая не была выделена new (а память, на которую указывает указатель после применения delete, таковой уже не является), и попытка такого использования delete как раз и приводит к ошибке. Решение:
Либо не вызывать деструктор вручную, либо в деструкторе писать name = 0, тогда при повторной попытке применить к name delete ничего не произойдёт - к нулевому указателю можно применять delete.
mansp
18 / 18 / 0
Регистрация: 07.11.2010
Сообщений: 136
07.04.2011, 18:14  [ТС]     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #11
Цитата Сообщение от silent_1991 Посмотреть сообщение
Эм.. А за каким... вы вызываете деструктор явно? Деструкторы вызывается автоматически по окончании времени жизни объекта (при выходе из блока, в котором объект был создан), и вызывать деструктор самостоятельно нет никакой необходимости. В данном случае у вас возникает такая ситуация:
1. Вы вызывается деструктор явно
2. Деструктор вызывается повторно при выходе из main.
В пункте 2 оператор delete пытается освободить память, которая уже была освобождена в пункте 1, и применять delete к указателю на память, которая не была выделена new (а память, на которую указывает указатель после применения delete, таковой уже не является), и попытка такого использования delete как раз и приводит к ошибке. Решение:
Либо не вызывать деструктор вручную, либо в деструкторе писать name = 0, тогда при повторной попытке применить к name delete ничего не произойдёт - к нулевому указателю можно применять delete.
Спасибо огромное))) буду внимательнее слушать лекции))
... а я его вручную вызывал постоянно от чего и выскакивала эта ошибка постянно... во я гоню....
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.04.2011, 18:19     _BLOCK_TYPE_IS_VALID при вызове деструктора класса
Еще ссылки по теме:

Программа выдаёт ошибку при вызове деструктора C++
C++ Ошибка при вызове деструктора
C++ При вызове деструктора вылазит ошибка _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
C++ При вызове деструктора выдается ошибка _BLOCK_TYPE_IS_VALID (pHead->nBlockUse)
Ошибка при вызове деструктора C++

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

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
07.04.2011, 18:19     _BLOCK_TYPE_IS_VALID при вызове деструктора класса #12
В простых классах (где не используются указатели и динамическое выделение памяти) деструктор можно вызывать и явно хоть 10 раз подряд - ничего не произойдёт. А вот когда вы в деструкторе самостоятельно освобождаете выделенную ранее память и не предотвращаете попытку её повторного освобождения - тут-то и начинаются проблемы.
Yandex
Объявления
07.04.2011, 18:19     _BLOCK_TYPE_IS_VALID при вызове деструктора класса
Ответ Создать тему
Опции темы

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