1 / 1 / 1
Регистрация: 22.03.2010
Сообщений: 71
1

Таинственный тип void

19.06.2011, 11:17. Показов 1903. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
правильно ли я освободил память?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
using namespace std;
 
int main(){
    void * mas[3];
 
    mas[0] = new int(17);
    mas[1] = new char('q');
    mas[2] = new bool(true);
 
    cout << *((int *)mas[0]) << endl;
    cout << *((char *)mas[1]) << endl;
    cout << *((bool *)mas[2]) << endl;
 
    for (int i = 0; i < 3; i++)
        delete mas[i];
 
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.06.2011, 11:17
Ответы с готовыми решениями:

Программа (не нахотиn тип void)
Вот написал программу с использованием классов и приминения конструктора и деструктора. При...

Перевести тип в void* и обратно
Добрый день. Суть: появилась необходимость создать map для хранения различных настроек. В...

Определить тип под void*
Возник у меня тут в процессе написания кода интерес академического характера. А именно узнать что...

Для чего нужен тип void?
для чего нужна функция void

12
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
19.06.2011, 11:46 2
получается, что неправильно, если компилятор g++ ругается.
0
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
19.06.2011, 12:09 3
у меня не ругается. Только я не понял всё-таки как он удаляет на что указывает void*
0
2022 / 1621 / 489
Регистрация: 31.05.2009
Сообщений: 3,005
19.06.2011, 12:21 4
Цитата Сообщение от pito211 Посмотреть сообщение
Только я не понял всё-таки как он удаляет на что указывает void*
Никак. delete к void* применять нельзя, это UB.
1
Android Programmer
141 / 142 / 10
Регистрация: 08.12.2010
Сообщений: 421
19.06.2011, 12:31 5
Цитата Сообщение от pito211 Посмотреть сообщение
у меня не ругается. Только я не понял всё-таки как он удаляет на что указывает void*
Память как висела, так и висит, оно то не ругается, но и не удаляет.
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
19.06.2011, 12:31 6
pito211, а ты используй вместо встроенных типов объекты. И в деструкторе напиши "Ой, меня удалили!". Подозреваю, что такой надписи ты не увидишь ни разу. А вот освободил ли компилятор блок памяти или нет — одному компилятору и известно, но так нельзя в любом случае.
0
935 / 760 / 299
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
19.06.2011, 12:31 7
Ничего здесь нет правильного тип void* это не типизированная куча байтов, в твоём примере ты выделил только три байта и причём тут массив ты записываешь в некуда, вот и при удаление может возникнуть ошибка, для этого нужно делать так, метод delete он основываеться на принятие типа void* - адреса памяти для удаления, вот правильный способ применение твоей задачи:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void**  mas = new void*[3];
mas[0] = new int(17);
mas[1] = new char('q');
mas[2] = new bool(true);
 
cout << *(int*) mas[0] << endl;
cout << *(char*) mas[1] << endl;
cout << *(bool*) mas[2] << endl;
 
for(int i = 0; i < 3; i++) 
    delete mas[i];
delete[] mas;
mas = NULL;
Ничего тут тайнственного нету в этом типе, наоборот универсальный тип, пока в С++ не стали использовать шаблоны template<typename>, единственным решением в С для передачи разных типов использовать void*
0
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
19.06.2011, 12:49 8
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int _tmain(int argc, _TCHAR* argv[])
{
    size_t              N = 5,  //Circles
                        M = 5;  //Conuses
    
    
 
    void *mas[5];
 
    
    for (int i = 0; i != 5; i++)
    {
        mas[i] = new Cone(4+i, 8+i);
 
    }
 
    for (int i = 0; i != 5; i++)
    {
        delete static_cast<Cone*>(mas[i]);
    }
 
    return 0;
}
вот так он нормально работает в MS VS. Вобщем надо указатели приводить к соответсвующему типу, тогда нормально удаляет
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
19.06.2011, 12:58 9
xAtom, это в твоём коде ничего правильного нет А в исходном только удаление по нетипизированному указателю
0
1 / 1 / 1
Регистрация: 22.03.2010
Сообщений: 71
19.06.2011, 12:59  [ТС] 10
Цитата Сообщение от grizlik78 Посмотреть сообщение
pito211, а ты используй вместо встроенных типов объекты. И в деструкторе напиши "Ой, меня удалили!". Подозреваю, что такой надписи ты не увидишь ни разу. А вот освободил ли компилятор блок памяти или нет — одному компилятору и известно, но так нельзя в любом случае.
спасибо за правильный пинок! действительно память не освобождается в моем случае.

Но вот нашел неожиданный выход!

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
#include <iostream>
 
using namespace std;
 
class A{
public:
    A(){ cout << "crated object A" << endl; }
    ~A(){ cout << "deleted object A" << endl; }
};
 
class B{
public:
    B(){ cout << "crated object B" << endl; }
    ~B(){ cout << "deleted object B" << endl; }
};
 
class C{
public:
    C(){ cout << "crated object C" << endl; }
    ~C(){ cout << "deleted object C" << endl; }
};
 
int main(){
    void * mas[3];
 
    mas[0] = new A;
    mas[1] = new B;
    mas[2] = new C;
 
    delete (A *)mas[0];
    delete (B *)mas[1];
    delete (C *)mas[2];
 
    return 0;
}
получаю

crated object A
crated object B
crated object C
deleted object A
deleted object B
deleted object C


помоему круто!

зы

компилятор от microsoft
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
19.06.2011, 13:19 11
xAtom,о чём речь? У ТС выделяется не три байта, выделяется массив из указателей на void, каждый имеет 4 байта размер (итого 12) и каждый инициализируется настолько грамотно, насколько позволяет работа с void*

Только у вас ещё до кучи конструируется указатель на массив из указателей на void. А у ТС этого нет, но у него всё равно указатель на массив указателей на void конструируется, пусть и неявно. Кстати, вот он:

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
#include <iostream>
 
using namespace std;
 
int main(){
        void * mas[3];
 
        mas[0] = new int(17);
        mas[1] = new char('q');
        mas[2] = new bool(true);
 
        cout << *((int *)mas[0]) << endl;
        cout << *((char *)mas[1]) << endl;
        cout << *((bool *)mas[2]) << endl;
 
        //Вот он        
        printf ("%x\n", mas);
        
        printf ("%x\n", mas[0]);
        printf ("%x\n", mas[1]);
        printf ("%x\n", mas[2]);
 
        getchar ();
        return 0;
 
}
И ошибку g++ выдаёт одну что на вашем коде что на тредстайтеровском. Так что у вас то же самое, только вид сбоку.

Добавлено через 15 минут
pontakrin, это чисто для познавания круто. на практике же вот:
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
#include <iostream>
 
using namespace std;
 
class A{
public:
        A(){ cout << "crated object A" << endl; }
        ~A(){ cout << "deleted object A" << endl; }
};
 
class B{
public:
        B(){ cout << "crated object B" << endl; }
        ~B(){ cout << "deleted object B" << endl; }
};
 
class C{
public:
        C(){ cout << "crated object C" << endl; }
        ~C(){ cout << "deleted object C" << endl; }
};
 
int main(){
 
        A a;
        B b;
        C c;
        getchar (); 
        return 0;
}
И не нужна лишняя сущность в виде массива указателей.

++++++++++++++++++++++++++++++++++++++++++++++++++=

Если же хочется использовать именно массив, то тут это уже моё сугубо лично мнение идёт, массив должен быть из каких-то однородных, что ли элементов. То есть оъекты A, B и С пусть будут объектами ОДНОГО класса. Но пусть в этом классе будет констуктор и соответственно A, B и С будут объектами одного класса, но сконструированными ПО-РАЗНОМУ. Так по-моему грамотно

В противном случае работаем с массивом указателей на объекты, которые ничё общего меж собой не имеют. Компилятор компилит, ну да. В общем, я бы над этим задумался дабы сразу приучиться к грамотному кодингу.
0
1 / 1 / 1
Регистрация: 22.03.2010
Сообщений: 71
19.06.2011, 13:30  [ТС] 12
Цитата Сообщение от kravam Посмотреть сообщение
И не нужна лишняя сущность в виде массива указателей.

++++++++++++++++++++++++++++++++++++++++++++++++++=

Если же хочется использовать именно массив, то тут это уже моё сугубо лично мнение идёт, массив должен быть из каких-то однородных, что ли элементов. То есть оъекты A, B и С пусть будут объектами ОДНОГО класса. Но пусть в этом классе будет констуктор и соответственно A, B и С будут объектами одного класса, но сконструированными ПО-РАЗНОМУ. Так по-моему грамотно

В противном случае работаем с массивом указателей на объекты, которые ничё общего меж собой не имеют. Компилятор компилит, ну да. В общем, я бы над этим задумался дабы сразу приучиться к грамотному кодингу.
а как же тогда в других языках существуют типы вроде variant и сollection. я вот считаю что накладывать стандарт на образ своего мышления не стоит потому что вам придется работать с чужими кодами, а у другого человека совсем другой тип мышления!
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
19.06.2011, 13:35 13
Я о С/C++, а не о других языках.
И мне не нравится создавать массив указателей на void и в чужих кодах я нормально ковырялся в силу своих умений- такое вижу впервые. А так-то у нас демократия. Чё хошь, то и делай. Компилятор хавает и ладно.
0
19.06.2011, 13:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.06.2011, 13:35
Помогаю со студенческими работами здесь

Void как подстановочный тип шаблона
Есть шаблон функции такого типа: template &lt;typename myClass, typename in_t, typename out_t,...

Что означает тип Class A __cdecl(void) ?
День добрый! Помогите разобраться с одним кодом, уже несколько часов голову ломаю. #include...

Как узнать тип, переданный через указатель на void?
есть функция, принимает LPVOID, нужно узнать как тип переменной был передан, и сколько занимает в...

Void menu(void); что это ? почему не void menu();
void menu(void); что это ? почему не void menu(); void naprimer(void); и это идет в классе это...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru