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

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

Войти
Регистрация
Восстановить пароль
 
VladSharikov
22 / 22 / 1
Регистрация: 02.12.2010
Сообщений: 824
#1

Динамическая память (строки), деструктор - C++

04.06.2012, 02:05. Просмотров 649. Ответов 9
Метки нет (Все метки)

Привет. Бьюсь уже час, помогите разобраться.
Написал программу, в одной функции память выделил, в другой освобождаю. После выполнения программы вылетает ошибка (вложение)


понял что ошибка в деструкторе. но конкретнее? что конкретно не так делаю???
речь про класс alcohol ! fluid работает отлично (тоже странно, одинаковые же блин!)
help!

zad1.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
#pragma once
#include "stdafx.h"
 
class fluid {
protected:
    char *name; // имя
    double density; // плотность напитка
public:
    fluid(void);
    fluid(char *, double);
 
    ~fluid(void);
 
    void print(void); // функция печати
};
 
class alcohol:public fluid {
    double strength; // крепость
public:
    alcohol(void);
    alcohol(char *_name, double _density, double _str);
    alcohol(char *_name);
 
    ~alcohol(void);
 
    void print(void);
    void set_density(double _density);
    void set_strength(double _str);
};
zad2.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
#include "stdafx.h"
#include <iostream>
 
#include "zad1.h"
 
fluid::fluid(void) {
    name = new char[13];
    strcpy(name, "Без названия");
    density = 0.;
}
 
fluid::fluid(char *_name, double _density) {
    name = new char[strlen(_name)+1];
    density = _density;
 
    strcpy(name, _name);
}
 
fluid::~fluid(void) {
    delete name;
}
 
void fluid::print(void) {
    std::cout << std::endl << "Напиток: " << name << ", плотность: " << density << std::endl;
}
 
alcohol::alcohol(void) {
    name = new char[13];
    strcpy(name, "Без названия\0");
    strength = 0;
    density = 0;
}
 
alcohol::alcohol(char *_name, double _density, double _str) {
    name = new char[strlen(_name)+1];
    density = _density;
    strength = _str;
    strcpy(name, _name);
}
 
alcohol::alcohol(char *_name) {
    name = new char[strlen(_name)+1];
    strcpy(name, _name);
 
    strength = 0;
    density = 0;
}
 
alcohol::~alcohol(void) {
    delete name;
}
 
void alcohol::print(void) {
    std::cout << std::endl << "Напиток: " << name << ", плотность: " << density << ", крепость: "<< strength << std::endl;
}
 
void alcohol::set_density(double _density) {density = _density;}
 
void alcohol::set_strength(double _str) {strength = _str;}
main
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "stdafx.h"
#include "zad1.h"
#include <iostream>
 
int main(void) {
    setlocale(LC_ALL, "Russian");
    fluid A("Water", 10.);
    A.print();
 
    alcohol B;
    B.print();
    return 0;
}
Извиняюсь кода спойлера не нашел.
Да. Не важно какой конструктор вызывать, результат один и тот же.
Миниатюры
Динамическая память (строки), деструктор  
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Памирыч
04.06.2012, 02:07
  #2

Не по теме:

Цитата Сообщение от VladSharikov Посмотреть сообщение
Извиняюсь кода спойлера не нашел
Если правильно понял, это теги [SPOILER]

gray_fox
What a waste!
1253 / 1136 / 54
Регистрация: 21.04.2012
Сообщений: 2,359
Завершенные тесты: 3
04.06.2012, 03:33     Динамическая память (строки), деструктор #3
Цитата Сообщение от VladSharikov Посмотреть сообщение
delete name;
delete[]
VladSharikov
22 / 22 / 1
Регистрация: 02.12.2010
Сообщений: 824
04.06.2012, 15:16  [ТС]     Динамическая память (строки), деструктор #4
gray_fox, поправил строку
C++
1
2
3
delete name; 
на 
delete [] name;
результат тот же. ошибка так же. я пробовал вчера это.

Не по теме:

Памирыч, спасибо буду знать

gray_fox
What a waste!
1253 / 1136 / 54
Регистрация: 21.04.2012
Сообщений: 2,359
Завершенные тесты: 3
04.06.2012, 15:39     Динамическая память (строки), деструктор #5
Ммм, понял, когда вызывается конструктор alcohol, сначала вызывается конструктор предка, там выделяется память, на нее указывает name, потом уже в конструкторе alcohol ещё раз выделяется память, и name уже указывает на другой участок памяти. Итого выделили два участка, на один указатель потеряли => память не освободили. Это раз. И два: дважды освобождение памяти по указателю name (вот здесь, видимо, и падало), сначала в деструкторе alcohol, потом - в fluid. Так работает:
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
#include <iostream>
#include <cstring>
 
 
class fluid {
protected:
    char *name; // имя
    double density; // плотность напитка
public:
    fluid(void);
    fluid(char const*, double);
 
    ~fluid(void);
 
    void print(void); // функция печати
};
 
class alcohol:public fluid {
    double strength; // крепость
public:
    alcohol(void);
    alcohol(char const* _name, double _density, double _str);
    alcohol(char const* _name);
 
    ~alcohol(void);
 
    void print(void);
    void set_density(double _density);
    void set_strength(double _str);
};
 
 
fluid::fluid(void) {
    name = new char[13];
    strcpy(name, "Без названия");
    density = 0.;
}
 
fluid::fluid(char const* _name, double _density) {
    name = new char[strlen(_name)+1];
    density = _density;
 
    strcpy(name, _name);
}
 
fluid::~fluid(void) {
    delete[] name;
}
 
void fluid::print(void) {
    std::cout << std::endl << "Напиток: " << name << ", плотность: " << density << std::endl;
}
 
alcohol::alcohol(void) : fluid("Без названия", 0), strength(0) {
    //name = new char[13];
    //strcpy(name, "Без названия"); //\0");
    //strength = 0;
    //density = 0;
}
 
alcohol::alcohol(char const* _name, double _density, double _str) : fluid(_name, _density), strength(_str) {}
 
alcohol::alcohol(char const* _name) : fluid(_name, 0), strength(0) {}
 
alcohol::~alcohol(void) {
    //delete[] name;
}
 
void alcohol::print(void) {
    std::cout << std::endl << "Напиток: " << name << ", плотность: " << density << ", крепость: "<< strength << std::endl;
}
 
void alcohol::set_density(double _density) {density = _density;}
 
void alcohol::set_strength(double _str) {strength = _str;}
 
 
int main() {
   fluid A("Water", 10.);
   A.print();
 
   alcohol B;
   B.print();
}
http://liveworkspace.org/code/3e290c...dff172cb1c7db8
И да, у С-шных строк тип - const char* (указатель на константу).
VladSharikov
22 / 22 / 1
Регистрация: 02.12.2010
Сообщений: 824
04.06.2012, 15:48  [ТС]     Динамическая память (строки), деструктор #6
Да, спасибо, все заработало, а можно еще объяснить , в чем я не прав?
gray_fox
What a waste!
1253 / 1136 / 54
Регистрация: 21.04.2012
Сообщений: 2,359
Завершенные тесты: 3
04.06.2012, 15:53     Динамическая память (строки), деструктор #7
ну я ж написал, 2 раза память выделяется, дважды удаляется по одному указателю, примерно так:
C++
1
2
3
4
char * name = new char[length]; // в конструкторе fluid
name = new char[length]; // в конструкторе alcohol, предыдущую память не освободили, а указателя на нее уже нет
delete[] name; // в деструкторе alcohol
delete[] name; // в деструкторе fluid, вот сдесь всё и упадёт
VladSharikov
22 / 22 / 1
Регистрация: 02.12.2010
Сообщений: 824
04.06.2012, 15:57  [ТС]     Динамическая память (строки), деструктор #8
понятно
я думал что конструкторы не наследуются
gray_fox
What a waste!
1253 / 1136 / 54
Регистрация: 21.04.2012
Сообщений: 2,359
Завершенные тесты: 3
04.06.2012, 16:00     Динамическая память (строки), деструктор #9
Они не наследуются, но при создании экземпляра класса вызываются в поряке от предка к потомку, по всей цепочке наследования. Если в конструкторе не указывать конструктор предка в списке инициализации, то будет вызван конструктор по умолчанию. Деструкторы выполняются в обратном порядке, от потомка к предку.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2012, 16:03     Динамическая память (строки), деструктор
Еще ссылки по теме:

Динамическая память C++
Ругается на деструктор (выделял динамически память). Почему? C++
C++ строки и динамическая память
Деструктор класса. Как правильно очистить память? C++
Деструктор и динамическая память C++

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

Или воспользуйтесь поиском по форуму:
VladSharikov
22 / 22 / 1
Регистрация: 02.12.2010
Сообщений: 824
04.06.2012, 16:03  [ТС]     Динамическая память (строки), деструктор #10
понял, спасибо
Yandex
Объявления
04.06.2012, 16:03     Динамическая память (строки), деструктор
Ответ Создать тему
Опции темы

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