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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.75
pontakrin
1 / 1 / 0
Регистрация: 22.03.2010
Сообщений: 71
19.06.2011, 11:17     Таинственный тип void #1
правильно ли я освободил память?

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;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
19.06.2011, 11:46     Таинственный тип void #2
получается, что неправильно, если компилятор g++ ругается.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
19.06.2011, 12:09     Таинственный тип void #3
у меня не ругается. Только я не понял всё-таки как он удаляет на что указывает void*
rangerx
1908 / 1517 / 139
Регистрация: 31.05.2009
Сообщений: 2,876
19.06.2011, 12:21     Таинственный тип void #4
Цитата Сообщение от pito211 Посмотреть сообщение
Только я не понял всё-таки как он удаляет на что указывает void*
Никак. delete к void* применять нельзя, это UB.
silentnuke
Android Programmer
137 / 138 / 5
Регистрация: 08.12.2010
Сообщений: 421
19.06.2011, 12:31     Таинственный тип void #5
Цитата Сообщение от pito211 Посмотреть сообщение
у меня не ругается. Только я не понял всё-таки как он удаляет на что указывает void*
Память как висела, так и висит, оно то не ругается, но и не удаляет.
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
19.06.2011, 12:31     Таинственный тип void #6
pito211, а ты используй вместо встроенных типов объекты. И в деструкторе напиши "Ой, меня удалили!". Подозреваю, что такой надписи ты не увидишь ни разу. А вот освободил ли компилятор блок памяти или нет — одному компилятору и известно, но так нельзя в любом случае.
xAtom
 Аватар для xAtom
910 / 735 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
19.06.2011, 12:31     Таинственный тип void #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*
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
19.06.2011, 12:49     Таинственный тип void #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. Вобщем надо указатели приводить к соответсвующему типу, тогда нормально удаляет
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
19.06.2011, 12:58     Таинственный тип void #9
xAtom, это в твоём коде ничего правильного нет А в исходном только удаление по нетипизированному указателю
pontakrin
1 / 1 / 0
Регистрация: 22.03.2010
Сообщений: 71
19.06.2011, 12:59  [ТС]     Таинственный тип void #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
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
19.06.2011, 13:19     Таинственный тип void #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 и С будут объектами одного класса, но сконструированными ПО-РАЗНОМУ. Так по-моему грамотно

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

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

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

В противном случае работаем с массивом указателей на объекты, которые ничё общего меж собой не имеют. Компилятор компилит, ну да. В общем, я бы над этим задумался дабы сразу приучиться к грамотному кодингу.
а как же тогда в других языках существуют типы вроде variant и сollection. я вот считаю что накладывать стандарт на образ своего мышления не стоит потому что вам придется работать с чужими кодами, а у другого человека совсем другой тип мышления!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.06.2011, 13:35     Таинственный тип void
Еще ссылки по теме:

Таинственный ответ программы, которая принимает число в 16ричной системе и переводит его в 10ричное C++
Typedef void (WINAPI *GLEND)(void), как вызывать? C++
Перевести тип в void* и обратно C++

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

Или воспользуйтесь поиском по форуму:
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
19.06.2011, 13:35     Таинственный тип void #13
Я о С/C++, а не о других языках.
И мне не нравится создавать массив указателей на void и в чужих кодах я нормально ковырялся в силу своих умений- такое вижу впервые. А так-то у нас демократия. Чё хошь, то и делай. Компилятор хавает и ладно.
Yandex
Объявления
19.06.2011, 13:35     Таинственный тип void
Ответ Создать тему
Опции темы

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