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

Дереференс указателей - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 5.00
Owyn
0 / 0 / 0
Регистрация: 28.05.2009
Сообщений: 64
30.07.2010, 01:16     Дереференс указателей #1
после прочтения мануала появилась необходимость использовать beth = *ted; но оно выдает еррор C2100 =\

надо:

есть size_t arg = 0x12345

нужно прочитать int по адресу из arg, можно ли это сделать поинтерами * или & ? или только кастом можно?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
30.07.2010, 01:56     Дереференс указателей #2
кто хоть что-нибудь понял - отзовитесь!
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
30.07.2010, 01:57     Дереференс указателей #3
& для получения адреса вообщем-то... Хотя я хз что вам надо...
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2293 / 1663 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
30.07.2010, 02:03     Дереференс указателей #4
Owyn, попробуй:
C++
1
int* p = reinterpret_cast<int*>(arg);
Owyn
0 / 0 / 0
Регистрация: 28.05.2009
Сообщений: 64
30.07.2010, 11:30  [ТС]     Дереференс указателей #5
cast
ну так вообще я и делал я спрашивал можно ли поинтеры потыкать и получить тож самое
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
30.07.2010, 11:44     Дереференс указателей #6
Цитата Сообщение от Owyn Посмотреть сообщение
поинтеры потыкать
C
1
2
size_t arg = 0x12345;
int i = *(int*)arg;
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
30.07.2010, 11:50     Дереференс указателей #7
Цитата Сообщение от Owyn Посмотреть сообщение
или только кастом можно?
Только кастом. Операция дереференса может применяться только к значению типа указатель
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
30.07.2010, 15:21     Дереференс указателей #8
Цитата Сообщение от Evg Посмотреть сообщение
Операция дереференса может применяться только к значению типа указатель
то есть вот такой фортель работать не должен?
C
1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main(void){
    int a = 13;
    int * pA = &a;
    size_t arg = (size_t)pA;
    printf("A = %d\n", *(int*)arg);
    return 0;
}
А работает. Хотя кому и зачем такое может понадобиться - не понятно...
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
30.07.2010, 18:19     Дереференс указателей #9
Цитата Сообщение от easybudda Посмотреть сообщение
то есть вот такой фортель работать не должен?
Ёлы-палы. Ты ж поставил операцию преобразования к указателю. И дереференс работает над значением типа указатель. А над типом int не будет работать (а точнее не может работать, потому как смысла у такой операции нет)
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
30.07.2010, 19:49     Дереференс указателей #10
Цитата Сообщение от Evg Посмотреть сообщение
А над типом int не будет работать (а точнее не может работать, потому как смысла у такой операции нет)
Ну да... Меня вот это суровое заключение смутило:
Цитата Сообщение от Evg Посмотреть сообщение
Только кастом.
Но тем не менее всё равно стрёмная затея. Есть переменные разных типов для хранения данных и переменные-указатели для хранения их адресов. И незачем их между собой путать.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
30.07.2010, 21:09     Дереференс указателей #11
Цитата Сообщение от easybudda Посмотреть сообщение
и переменные-указатели для хранения их адресов
Чем по твоему адрес отличается от целого числа? На уровне машины - ничем. Различие есть только на уровне языка, да и то выражается лишь в типе выражения

Цитата Сообщение от easybudda Посмотреть сообщение
И незачем их между собой путать
Да вроде как никто их пока тут и не путает. Что касается топикстартера - у меня есть смутные подозрения, что человек работал с ассемблером, но не имеет навыков работы на си. Он ничего не путает а просто спрашивает

Да, забыл ещё упомянуть. Дереференс можно делать только над поинтером по следующей причине. Если есть указатель типа int*, то дереференс означает чтение (или запись) фрагмента памяти размером в 4 байта (размер int'а), если есть указатель типа double*, то фрагмент памяти имеет размер 8 байт и т.п. Имея на руках лишь адрес в виде int'а (но не поинтера) мы такой информацией не обладаем, а потому по языку невозможно физически строить подобную операцию. Это принципиальное отличие между понятиями "адрес" и "указатель": указатель как сущность описывает не только адрес, но и размер
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
30.07.2010, 22:29     Дереференс указателей #12
Цитата Сообщение от Evg Посмотреть сообщение
Чем по твоему адрес отличается от целого числа? На уровне машины - ничем. Различие есть только на уровне языка, да и то выражается лишь в типе выражения
Само собой, ничем не отличается. Но такой подход - прямой путь к куче трудноуловимых ошибок.

вот, кстати, ещё для разнообразия
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int main(void){
    int a = 13;
    union {
        size_t num;
        int * ptr;
    } un;
    
    un.ptr = &a;
    
    printf("a = %d, &a = %#x\n", *(un.ptr), un.num);
    
    return 0;
}
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
31.07.2010, 13:36     Дереференс указателей #13
Цитата Сообщение от easybudda Посмотреть сообщение
вот, кстати, ещё для разнообразия
Подход с преобразованием int'а НИКОГДА не приведёт к ошибке. В разумном предположении, что нужный нам адрес (но не режим адресации на машине) укалывается в размер int'а.

Твой подход приведёт к ошибке, если размер size_t не совпадает с размером int* (чего не будет при использовании cast'а). Твой подход заведомо не будет работать на архитектурах, где преобразование целого в указатель требует дополнительных действий (например, навешивание тэгов на число на защищённых архитектурах или специфические пляски с бубнами на сигнальных процессорах), потому что в твоём случае преобразования типов нет, хотя по логике постановки задачи оно должно быть.

Ну и твой способ неверен чисто с концептуальной точки зрения: преобразование типа (cast) НЕ является операцией наложения битового представления. Преобразование от int'а к float'у - это cast. При наложении битов получится неправильный результат. float от указателя принципиально ничем не отличается - происходит преобразование значения (а не его битового представления) из одного типа в другой. Наверняка есть сигнальные процессоры, в которых твой способ ошибочно отработает даже при преобразовании int'а к unsigned'у, потому что для представления целых чисел используется кодировка не в обратном коде, а в прямом (я не силён в терминологии и не помню точно, как это называется)

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

Добавлено через 1 минуту
Цитата Сообщение от easybudda Посмотреть сообщение
Но такой подход - прямой путь к куче трудноуловимых ошибок
К слову говоря, это твой подход является путём к созданию кучи ошибок
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
31.07.2010, 15:38     Дереференс указателей #14
Цитата Сообщение от Evg Посмотреть сообщение
Твой подход приведёт к ошибке, если...
Твой подход заведомо не будет работать на архитектурах, где...
твой способ неверен чисто с концептуальной точки зрения...
твой подход является путём к созданию кучи ошибок...
Ну и краткий итог. При работе через cast выполняется преобразование типа для значения. При работе через union происходит копирование битового образа (которое ещё и неправильно отработает, если битовые размеры типов не совпадают). Если твой пример работает на i386, то это вовсе не означает, что этот пример будет корректно работать на всех архитектурах
Ага... И ещё с десяток причин можно назвать, почему оно не правильно. А где я говорил, что нужно так делать? Просто частный случай.
Раз уж так серьёзно к вопросу подходите, покажите мне малограмотному, как хранить адреса в переменных целочисленного типа так, чтобы это работало везде от майнфреймов до тетрисов. И главный вопрос, который я уже в третий раз задаю - зачем и кому это вообще нужно?!
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
31.07.2010, 16:00     Дереференс указателей #15
Цитата Сообщение от easybudda Посмотреть сообщение
И ещё с десяток причин можно назвать, почему оно не правильно.
Если тебе не интересно - не читай. На форуме ты не один, есть люди, кому это будет интересно, есть начинающие, кому это будет полезно для самообразования

Цитата Сообщение от easybudda Посмотреть сообщение
А где я говорил, что нужно так делать?
Андрей, может не стоит уподобляться товарищу DenQ?

Цитата Сообщение от easybudda Посмотреть сообщение
Просто частный случай.
Частный случай, который не является правильным с концептуальной точки зрения. Я понимаю, что данный аспект вопроса тебя мало интересует, но начинающим, на мой взгляд, очень важно этот момент понимать. Так или иначе подавляющему большинству людей за всю программистскую карьеру приходится работать только с одной платформой или только с одним процессором, а потому попросту не удаётся понять на практике большинство из проблем переносимости. Но, опять-таки на мой взгляд, это не должно являться поводом к тому, чтобы не уметь писать программы "правильно"

Цитата Сообщение от easybudda Посмотреть сообщение
Раз уж так серьёзно к вопросу подходите, покажите мне малограмотному, как хранить адреса в переменных целочисленного типа так, чтобы это работало везде от майнфреймов до тетрисов.
При чём тут мэйнфрэймы и тетрисы я не особо понял, но ответ на вопрос: никак. Целое и указатель являются разными типами, которые в общем случае нельзя тождественно привести один в другое и обратно (так же, как нельзя тождественно перевести плавающее в целое и обратно)

Цитата Сообщение от easybudda Посмотреть сообщение
И главный вопрос, который я уже в третий раз задаю
Не стану уподобляться вышеобозначенному товарищу и не стану с пеной у рта доказывать, что вопрос ты задаёшь только в первый раз

Цитата Сообщение от easybudda Посмотреть сообщение
зачем и кому это вообще нужно?!
"Это" - это что? Если знания и понимания, то ответ очевиден: тот, кто сочтёт эти знания полезными, тот их усвоит, тот, кто сочтёт эти знания бесполезными - молча пройдёт мимо.

Если "это" - хранение адреса в целом, то в качестве реального примера загляни в файл /usr/include/elf.h на юниксах. Структуры, описывающие внутренний формат файла содержат данные, которые по своей сути являются указателями, но хранятся в виде адресов в целочисленных типах

Или под "это" имелось в виду что-то другое?
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
31.07.2010, 16:17     Дереференс указателей #16
Цитата Сообщение от Evg Посмотреть сообщение
Если "это" - хранение адреса в целом
ага, я про это и спрашивал.
Цитата Сообщение от Evg Посмотреть сообщение
в качестве реального примера загляни в файл /usr/include/elf.h на юниксах.
Вот за это спасибо - интересно...
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
31.07.2010, 16:24     Дереференс указателей #17
Цитата Сообщение от easybudda Посмотреть сообщение
Вот за это спасибо - интересно...
Такое нужно для программ по типу загрузчиков. Они работают с непосредственными адресами в памяти, но тем не менее эти адреса они не трактуют как указатели, потому как работают НЕ с объектами (переменными). Адрес трактуется как обычное число в некоей сплошной адресации памяти. При загрузке сегментов в память работа с адресами идет как с long'ами, потому как фактически идёт маппирование памяти средствами ОС. Потом когда начинается процесс настройки адресов (resolve), то такие целочисленные адреса преобразуются в указатели, потому как на Си косвенное обращение возможно только через величину типа указатель
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
31.07.2010, 17:01     Дереференс указателей #18
из /usr/include/sys/elf32.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
/*
 * ELF definitions common to all 32-bit architectures.
 */
 
typedef u_int32_t       Elf32_Addr;
/* ... */
 
/*
 * ELF header.
 */
 
typedef struct {
/* ... */
        Elf32_Addr      e_entry;        /* Entry point. */
/* ... */
} Elf32_Ehdr;
 
/*
 * Section header.
 */
 
typedef struct {
/* ... */
        Elf32_Addr      sh_addr;        /* Address in memory image. */
/* ... */
} Elf32_Shdr;
ну в общем да, так нагляднее...
кстати, оттуда же
C
1
2
3
4
5
6
7
typedef struct {
        Elf32_Sword     d_tag;          /* Entry type. */
        union {
                Elf32_Size      d_val;  /* Integer value. */
                Elf32_Addr      d_ptr;  /* Address value. */
        } d_un;
} Elf32_Dyn;
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
31.07.2010, 17:18     Дереференс указателей #19
Цитата Сообщение от easybudda Посмотреть сообщение
кстати, оттуда же
Это не есть случай, как из твоего примера. В union'е просто хранится величина либо одного, либо второго типа, в зависимости от значения d_tag. К преобразованию типа никакого отношения не имеет

Добавлено через 1 минуту
Цитата Сообщение от easybudda Посмотреть сообщение
ну в общем да, так нагляднее...
Это не для наглядности. Просто большинство сервисных программ, работающих непосредственно с бинарным форматом, работают с адресами как с числами. Это не могут быть указатели, потому как работа идёт с файлом, который в память не загружен
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.07.2010, 18:03     Дереференс указателей
Еще ссылки по теме:

Создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей C++
Создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей C++
Копирование указателей C++

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

Или воспользуйтесь поиском по форуму:
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
31.07.2010, 18:03     Дереференс указателей #20
Цитата Сообщение от Evg Посмотреть сообщение
Это не есть случай, как из твоего примера.
Да знаю... По сути у обоих параметров тип u_int32_t, просто напомнило Кстати, зачем столько названий для типа unsigned int? unint32_t, u_int32_t, __uint32_t...

Цитата Сообщение от Evg Посмотреть сообщение
Это не для наглядности.
Ну в смысле - мне нагляднее, я же не понимал, зачем адреса в целочисленных переменных хранить...
Yandex
Объявления
31.07.2010, 18:03     Дереференс указателей
Ответ Создать тему
Опции темы

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