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

универсальный указатель - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.92
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
24.02.2013, 22:46     универсальный указатель #1
Добрый вечер.
Можно ли создать шаблон, что бы не приводить явно универсальный указатель к определенному типу при разыменовании?
Или по крайней мене узнать тип (размер) данных которые хранятся по указанному адресу?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.02.2013, 22:46     универсальный указатель
Посмотрите здесь:

Специализация и обобщение в С++ через универсальный указатель C++
универсальный указатель C++
C++ Функция принимает указатель на void и возвращает указатель на int
C++ Как получить ссылку на указатель или указатель на указатель в массиве?
Реализация двоичных деревьев поиска: Зачем в параметрах функции используется указатель на указатель C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
25.02.2013, 02:59     универсальный указатель #21
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
а как же qsort, memset memcpy и прочий stdlib.h???
А они не являются С++ функциями и использовать их в С++ стоит только в уникальных случаях (ровно как и void*).
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
25.02.2013, 04:33     универсальный указатель #22
Цитата Сообщение от ForEveR Посмотреть сообщение
А они не являются С++ функциями и использовать их в С++ стоит только в уникальных случаях (ровно как и void*).
С++ мультипарадигменый язык, на нём можно успешно программировать и без ООП и шаблонов. То, что их добавили в С++, не значит, что Си-стиль хуже. Он просто другой.

Вот стоит перед тобой задача заполнить N байт по адресу 0x00ABCDEF значениями 0x01
Разве memset для такой задачи не подходит лучше всего?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
25.02.2013, 10:35     универсальный указатель #23
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Мультипарадигменность — не разрешение делать что угодно. Любой язык общего назначения при должном возрасте становится мультипарадигменным.

Немного помесить память с помощью memset() — это именно что уникальный случай. Если это надо делать часто, то возникает вопрос, зачем вам вообще Плюсы и не перекроет ли оверхед Плюсов все выгоды от memset().

Но вот использовать qsort() в плюсовом коде — это как прийти на автозавод и обнаружить, что всё собирается на конвейере, но дырку под лобое стекло самолично выпиливает безопилой дядя Вася. Это работает, Вася виртуозен и делает всё правильно, вовремя и не отрезает себе ноги, но у инспектора по технике безопасности глаза на лоб полезут и он сразу побежит спрашивать инженеров: "На кой хрен, если у вас тут безопасных механизмов с автоматическим контролем хоть ложкой ешь?" И ведь действительно, на кой хрен? Только потому, что кто-то хорошо знает дядю Васю и поленился настроить ещё один автомат?
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
26.02.2013, 15:26  [ТС]     универсальный указатель #24
Что бы не создавать новую тему дополню вопрос тут, тем более что он связан с темой топика...
Архитектура машины (разрядность), определяет не только общий объем памяти, но и размер ячейки памяти?
К примеру long long доступно только на 64 разрядной платформе (не зависимо от системы)?
Если для хранения переменной нам достаточно, к примеру, 1-2 байта, как выставлены остальные?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
26.02.2013, 23:48     универсальный указатель #25
Цитата Сообщение от fuelcs Посмотреть сообщение
Архитектура машины (разрядность), определяет не только общий объем памяти, но и размер ячейки памяти?
Память всегда разбита на минимальные адресуемые ячейки — байты. От разрядности зависят размеры регистров (а от них косвенно быстродействие), размеры адресного пространства. Размеры конкретных типов данных зависят от языка, компилятора и рантайма.
Цитата Сообщение от fuelcs Посмотреть сообщение
К примеру long long доступно только на 64 разрядной платформе (не зависимо от системы)?
На любой. Просто на 32-битных платформах он точно не влезет в один регистр, так что работа с такими числами будет выполняться несколько медленнее.
Цитата Сообщение от fuelcs Посмотреть сообщение
Если для хранения переменной нам достаточно, к примеру, 1-2 байта, как выставлены остальные?
Зависит от типа данных. От него же зависит понятие "достаточности" и "лишнего места". С точки зрения языка лишних байтов вообще нет. Для целых чисел при кодировании дополнительным кодом незначащие биты установлены в нули для положительных и в единицы для отрицательных чисел.
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 01:38  [ТС]     универсальный указатель #26
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Память всегда разбита на минимальные адресуемые ячейки — байты
Не совсем понятен принцип работы... К примеру, указатель (int *) указывает на что? Первый-последний байт? В процессе работы программы осуществляется "сборка" числа? Вот пример кода с другого топика Стек и куча:
Assembler
1
2
3
4
5
6
7
8
9
    movl    $0, -4(%rbp)
    jmp .L2
.L3:
    addl    $1, -4(%rbp)
.L2:
    cmpl    $4, -4(%rbp)
    setle   %al
    testb   %al, %al
    jne .L3
-4(%rbp) - обращение в стек к переменной, $4 - это ее размер в байтах?
Возможно вопросы примитивные, но нагуглить что-то стоящее тяжело...

Добавлено через 30 минут
Работу с память, в следующем примере, рассматриваю как "черный ящик":
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;
int main ()
{
    unsigned short a=1;
    void *p1=&a;
    cout << *(int*)p1 << "\n";//
    char b=(char)1;
    void *p2=&b;
    cout <<  *(int*)p2 << "\n";
    return 0;
}
Вывод:
-859045887 (1111111111111111111111111111111111001100110011000000000000000001)
-858993663 (1111111111111111111111111111111111001100110011001100110000000001)

Вывод программы в двоичной системе отличается в один байт...

Вот и решил что так и хранится переменная в памяти...
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
27.02.2013, 02:05     универсальный указатель #27
ты уже вообще перемудрил чего-то. Не воспринимай это дело так серьёзно. При чём здесь вообще указатели в твоём примере?
char занимает 1 байт, int - 4
ты присвоил значение 1 байту по адресу &a
а вывел значение 4х байт по этому адресу.
естесственно, все они кроме младшего - случайно оказавшиеся в памяти числа (ну, может не совсем случайно, но к твоим переменным отношение не имеют, они просто за ними стояли.)
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
27.02.2013, 02:44     универсальный указатель #28
Цитата Сообщение от fuelcs Посмотреть сообщение
К примеру, указатель (int *) указывает на что? Первый-последний байт?
На первый байт. На тот, у которого адрес меньше.
Цитата Сообщение от fuelcs Посмотреть сообщение
В процессе работы программы осуществляется "сборка" числа?
При чтении из памяти куска из четырёх байт они автоматически собираются из четырёх отдельных байтов в 32-битное число в регистре. Хитрость в том, что число 0x12345678 в памяти может храниться и как 0x78, 0x56, 0x34, 0x12, так и в виде 0x12, 0x34, 0x56, 0x78 (int* указывает на левый байт в этих последовательностях). Гуглите endianness.
Цитата Сообщение от fuelcs Посмотреть сообщение
Вот пример кода с другого топика
-4(%rbp) - обращение в стек к переменной, $4 - это ее размер в байтах?
-4(%rbp) — ага, это обращение к переменной из стека.
$4 — а вот это просто число 4.
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 13:13  [ТС]     универсальный указатель #29
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
все они кроме младшего - случайно оказавшиеся в памяти числа
Не согласен насчет "случайных" чисел, "мусор" - да, но не случайный...
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <conio.h>
using namespace std;
int main ()
{
    short a;
    int b;
    cout << a << "\n";
    cout << b << "\n";
    return 0;
}
Вывод:
-13108 (111111111111111111111111111111111111111111111111 1100 1100 1100 1100)
-858993460 (11111111111111111111111111111111 1100 1100 1100 1100 1100 1100 1100 1100)

Добавлено через 21 минуту
К чему это все я? Получается что из за наличия "мусора" в памяти, можно программно определить тип переменных которые находятся в ячейке, на которую указывает указатель типа void*?
По крайней мере для без знаковых переменных...
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
27.02.2013, 13:40     универсальный указатель #30
Цитата Сообщение от fuelcs Посмотреть сообщение
К чему это все я? Получается что из за наличия "мусора" в памяти, можно программно определить тип переменных которые находятся в ячейке, на которую указывает указатель типа void*?
бред полнейший, что курил!?
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 14:14  [ТС]     универсальный указатель #31
И вот что еще у меня получилось:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <conio.h>
using namespace std;
int main ()
{
    short a;
    int b;
    cout << (int)&a - (int)&b;
    return 0;
}
По идеи переменные должны лежать рядом в стеке, а разница между адресами 12. То есть получается, что на хранение одной переменной выделяется 12 байт (96 бит)?
Интересно было бы увидеть еще машинный код...
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
27.02.2013, 14:18     универсальный указатель #32
Цитата Сообщение от fuelcs Посмотреть сообщение
По идеи переменные должны лежать рядом в стеке, а разница между адресами 12. То есть получается, что на хранение одной переменной выделяется 12 байт (96 бит)?
выставь release
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 14:25  [ТС]     универсальный указатель #33
Цитата Сообщение от Jupiter Посмотреть сообщение
бред полнейший, что курил!?
Почему бред? При разыменовании указателя мы всегда будем получать отрицательное число если тип не сходится...
Причем в двоичной форме старшие биты будут иметь одинаковый вид...
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
27.02.2013, 14:30     универсальный указатель #34
Цитата Сообщение от fuelcs Посмотреть сообщение
Почему бред?
потому что указатель на воид на то и воид, чтоб хранить адрес и не знать что лежит по этому адресу.
если это ваша программа - то вы знаете что там лежит.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
27.02.2013, 21:39     универсальный указатель #35
Цитата Сообщение от fuelcs Посмотреть сообщение
При разыменовании указателя мы всегда будем получать отрицательное число если тип не сходится...
И что? И зачем тебе это? Я потерял нить разговора. А завтра ты откроешь для себя union и будешь без всяких операций с адресами преобразовывать 1 байт в 4 байта... или чего ты там хотел?
В чём суть вопроса то?
vua72
410 / 410 / 83
Регистрация: 28.11.2010
Сообщений: 1,158
27.02.2013, 23:39     универсальный указатель #36
Вообще-то внутренний формат хранения данных зависит от архитектуры, и здесь правильно указали, что для большинства минимальной единицей является 1 байт + порядок байт (little или big endian) + размер переменных зависит от архитектуры и оси тоже. И вывод вашей программы у меня
./a.out
вывод:
0
0
и что мы тут будем ловить?

Добавлено через 2 минуты
ну и ошибка к последнему коду
trashh_cpp/main.cpp:7:29: error: cast from ‘int*’ to ‘int’ loses precision [-fpermissive]
fuelcs
12 / 12 / 0
Регистрация: 23.01.2013
Сообщений: 143
02.03.2013, 00:09  [ТС]     универсальный указатель #37
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
В чём суть вопроса то?
суть вопроса изложил в первом посте... И лучше поздно чем никогда, все таки признать свою ошибку... По содержимому ячейки памяти узнать тип переменной которая там хранится невозможно, что мне сразу же написали...
Но все же всем спасибо за ответы, по ходу прояснил себе некоторые моменты...
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
02.03.2013, 00:56     универсальный указатель #38
Ну почему сразу нельзя. Можно. Если вы сами рядом с ячейкой положите этот тип. И будете его обновлять при присваиваниях. Но да, конечно, всё это под честное слово, что там будет действительно лежать тип, а не мусор.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.03.2013, 02:18     универсальный указатель
Еще ссылки по теме:

Функция, получающая указатель на обычную функцию, получает указатель на метод класса C++
Универсальный указатель или универсальный скалярный тип C++
C++ Как правильно удалять выделенную память под указатель на указатель?

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

Или воспользуйтесь поиском по форуму:
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4920 / 2663 / 243
Регистрация: 29.11.2010
Сообщений: 7,405
02.03.2013, 02:18     универсальный указатель #39
Это как брать черные коробки и подписывать что в них есть, а потом в одной из них будет лежать бомба, а написано "любимой маме на 8 марта"
Yandex
Объявления
02.03.2013, 02:18     универсальный указатель
Ответ Создать тему
Опции темы

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