Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> приведение типа, запуталсо 
V
    Опции темы
BearFear
Дата 10.11.2012, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



Уважаемые знатоки! Прошу помощи в одном глупом вопросе!

имеется ситуация:
Код

unsigned int *UIntegerPointer = new unsigned int(666);
unsigned long long *ULoooongerPoiter = reinterpret_cast<unsigned long long*>(UIntegerPointer);


По идее, при разыменовании ULoooongerPoiter мы прочитаем произвольные 4 байта.

Вопрос:
Как сделать так, что бы ->
Код

// где то в старой москве происходит создание указателя на unsigned long long
unsigned long long *_BlockSize;
...
void set_data(unsigned char *BlockSize) {
    _BlockSize = ?
}


Всю голову сломал. Необходимо много методов, где в качестве аргумента принимается указатель на число без точки. Метод принимающий указатель должен сохранить указатель вне зависимости от типа и безопасно работать в дальнейшем как с unsigned long long. Поможите пожлста кто чем может, а то мой мозг лопнет.

Добавлено через 10 минут и 31 секунду
Вдруг если вопрос описал неясно. В общем вот такой постой класс состоящий из сеттеров и геттеров.

Код

class query_read {
public:
    void set_query(void* Data, unsigned char *Size);
    void set_query(void* Data, unsigned short *Size);
    void set_query(void* Data, unsigned long *Size);
    void set_query(void* Data, unsigned long long *Size);
    void set_query(void* Data, unsigned int *Size);

    void *get_data();
    unsigned long long *get_size();

private:
    void *_Data;
    unsigned long long *_Size;
}


Думаю нет смыслу вписывать тело функций, и так понятно что 5 методов позволяют присвоить _Data и _Size значения и 2 метода возвращают эти значения. То есть, данный класс всего лишь хранит какую то простенькую информацию.

Это сообщение отредактировал(а) BearFear - 10.11.2012, 09:34
PM MAIL   Вверх
BearFear
Дата 10.11.2012, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



Неужели прямо безвыходная ситуация? :(
PM MAIL   Вверх
volatile
Дата 10.11.2012, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



BearFear, много букв, 
два раза прочитал, так и не понял что вы хотите.
Цитата(BearFear @  10.11.2012,  09:29 Найти цитируемый пост)
Метод принимающий указатель должен сохранить указатель вне зависимости от типа и безопасно работать в дальнейшем как с unsigned long long.

если это и есть вопрос тогда так:
Цитата(BearFear @  10.11.2012,  09:29 Найти цитируемый пост)
class query_read {
public:
    void set_query(void* Data, unsigned char *Size);
    void set_query(void* Data, unsigned short *Size);
    void set_query(void* Data, unsigned long *Size);
    void set_query(void* Data, unsigned long long *Size);
    void set_query(void* Data, unsigned int *Size);

    void set_query(void* Data, void *Size)
    { 
       ...
       _Size = (unsigned long long *)Size; 
    };


Цитата(BearFear @  10.11.2012,  09:29 Найти цитируемый пост)
По идее, при разыменовании ULoooongerPoiter мы прочитаем произвольные 4 байта.

нет long long это наверняка 8 байт.

Цитата(BearFear @  10.11.2012,  09:29 Найти цитируемый пост)
принимается указатель на число без точки. 

что такое число без точки?

Добавлено @ 12:03
и еще
_Size это же размер,  нафига он у вас указатель я так и не понял.


Это сообщение отредактировал(а) volatile - 10.11.2012, 12:09
PM MAIL   Вверх
BearFear
Дата 10.11.2012, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



проверочный код
Код

    unsigned int *UIntegerPointer = &TrueInt[0];
    unsigned long long *ULoooongerPoiter = reinterpret_cast<unsigned long long*>(UIntegerPointer);
    printf("%llu\n", *ULoooongerPoiter);


смысл класса, получить указатель на любой тип указния размера, но сохранить его как указатель на unsigned long long. Нужен этот класс для формирования динамических структур на лету.

Цитата

нет long long это наверняка 8 байт.

да, и unsigned int наверняка 4 байта. В этом случае 4 байта читаем произвольные.

То есть, указатель на размер, может являться ранее записанным блоком данных. Например для этономии места в файле, мы пишем unsigned char значение экономящее 7 байт и саму строку не надо делать фиксированной длины. Да, можно использовать приведения во вложенных циклах и делать сотни строк кода. Надо что бы был класс, так как процедуру опроса очереди можно сделать параллельной. Отсюда потребность в очереди вариативных объектов описывающих задание. Ну эт пофиг. 

Приведение в стиле Си.... 
Код

    unsigned int TrueInt[2] = {666, 666};
    unsigned int *UIntegerPointer = &TrueInt[0];
    unsigned long long *ULoooongerPoiter = (unsigned long long*)UIntegerPointer;
    printf("%llu\n", *ULoooongerPoiter);


тот же результат, 0x29A0000029A. То есть, мы читаем произвольные 4 байта.

Это сообщение отредактировал(а) BearFear - 10.11.2012, 12:38
PM MAIL   Вверх
volatile
Дата 10.11.2012, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(BearFear @  10.11.2012,  09:29 Найти цитируемый пост)
  unsigned long long *_Size;

BearFear, нахрена у вас сайз указатель?
ответьте только на это

PM MAIL   Вверх
BearFear
Дата 10.11.2012, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



Ну ребят, наверно я не так все высказал. Вы уж сори если что. В общем надо что бы:
- на входе указатель произвольного типа POD (за искл. float / double / long double)
- на выходе указатель unsigned long long

указатель _Size для определения размера блока памяти void*. И блок памяти void* может потенциально быть указателем размера другого блока. Смысл в этом.

Это сообщение отредактировал(а) BearFear - 10.11.2012, 12:55
PM MAIL   Вверх
volatile
Дата 10.11.2012, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(BearFear @  10.11.2012,  12:54 Найти цитируемый пост)
указатель _Size для определения размера блока памяти void*. 

кажется дошло.
вы не понимаете что такое указатели.

_Size это не указатель, это размер - беззнаковое целое.

Вероятно вам нужно что-то подобное:
Код

class query_read {
public:
    template <typename T>
    void set_query (T * Data, size_t Size)
    {
       _Data = (unsigned long long *) Data;
       _Size = Size * sizeof (T) / sizeof (long long);
    }

    unsigned long long * get_data () { return _Data; }
    size_t get_size() { return _Size; }

private:
    unsigned long long *_Data;
    size_t _Size;
};


Вообще вам рано заниматься такими вещами.
Нужно еще раз внимательно прочитать и усвоить что такое указатели, что такое целые числа.
т.е самые основы языка. 
Без этого в языке ничего нельзя сделать.




PM MAIL   Вверх
BearFear
Дата 10.11.2012, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



Неплохая идея с параметризацией методов... кстати! Про указатели знаем, собаку съели еще года два назад. Указатель есть ничто иное как переменная хранящая адрес. В С/C++ языке это пишется немного с подковыркой. Другое дело ссылки... хотя так же не лишены тонкостей. Повторюсь, проблема была в том, что указатель и его тип, никак не влияет на значение на которое он указывает. То есть, приведение (реинтерпретация) указателя не приведет к тому, что в рантайме все будет ок. Может я просто не так выразил задачу. Решение у самого вертится на языке но не могу сообразить.

До этого, я думал вообще указывать размер в виде void* и подставлять sizeof или контстанты определенные на стадии компиляции. В самом объекте просто делать выбрку типа по размеру соответствующему константам. Это позволило бы делать "указатель на что угодно". А уже при присваивании значения, делать временную переменную нужного типа и писать по указателю значение соответствующего типа. По сути, все упирается в число байт расположенных в блоке памяти на который указывает указатель. Их всего 5, uchar, ushort, ulong, ulonglong, uint. Сделать 5 дефайнов размера + флаг int или один из ...
ваще шаблоны решают все в данном случае. Разве что эстетика будет хромать, писать в одном модуле.


Volatile, параметризация в вашем примере позволяет работать только с типами данных. А что если длина данного 45 байт?

Это сообщение отредактировал(а) BearFear - 10.11.2012, 13:45
PM MAIL   Вверх
volatile
Дата 10.11.2012, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



BearFear, вам нужно подождать feodorv, это человек не только с высочайшей квалификацией, но и обладающий дьявольским (или ангельским) терпением, и умением объяснять. (Если он пожелает конечно)
Я не могу, соори.
могу сорваться.
 smile 


Это сообщение отредактировал(а) volatile - 10.11.2012, 14:34
PM MAIL   Вверх
BearFear
Дата 10.11.2012, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



Эт плохо. Терпение наше всё.
PM MAIL   Вверх
feodorv
Дата 10.11.2012, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



volatile,  smile Спасибо за высокую оценку проделываемого труда. И попробую вмешаться.

Не понятно что хочется и зачем хочется. 

Если хочется хранить указатель на некоторую память (которая может представлять собой и символ, и набор символов, и целочисленное значение различного диапазона, да что там стесняться, и  число с плавающей точкой), то нужно заводить неименованный указатель void*. Чтобы всё-таки помнить, на память какого типа указывает этот самый указатель, придётся отдельно хранить тип этого указателя. В C это выглядело бы так:
Код

enum
{
  PTRTYPE_UCHAR,
  PTRTYPE_USHORT,
  PTRTYPE_UINT,
  PTRTYPE_ULONGLONG,
  PTRTYPE_BLOB
} ptrtype;

struct ptr
{
  void *p;
  ptrtype type;
};


Тогда взятие целочисленного значения по этому самодельному указателю выглядело бы следующим образом:
Код

unsigned long long getSize( struct ptr *p )
{
  switch( p->type )
  {
    case PTRTYPE_UCHAR:
       return *(unsigned char *) p->p;
    case PTRTYPE_USHORT:
      return *(unsigned short *) p->p;
    case PTRTYPE_UINT:
      return *(unsigned int *) p->p;
    case PTRTYPE_ULONGLONG:
      return *(unsigned long long *) p->p;
    default:
      return *(size_t *) p->p; // <- anything you like
}


Но вот зачем эту нужно? Что это решает? 
Цитата(BearFear @  10.11.2012,  13:32 Найти цитируемый пост)
Например для этономии места в файле, мы пишем unsigned char значение экономящее 7 байт

Экономите в одном месте, теряете в другом. Приходится хранить и указатель, и тип указателя. В производительности тоже потери: свичи и выборка невыровненных данных будут съедать время. И потери, судя по всему, будут значительно больше и ощутимее. Но хозяин барин.

ЗЫ Для C++, как смутно припоминается, было какое-то элегантное решение вопроса, но увы, его не помню.


BearFear, простите за эту правду, но очень много неточностей в Ваших высказываниях. Не буду касаться бесконечно возникающих ниоткуда "произвольных 4-х байт". Рассмотрим Ваши последние утверждения:

Цитата(BearFear @  10.11.2012,  14:19 Найти цитируемый пост)
Указатель есть ничто иное как переменная хранящая адрес.

Это не так. Действительно, значением указателя является некий адрес в адресном пространстве процесса. Но указатель к этому адресу не сводится никоим образом. Указатель - это тип переменной в языке (для этого типа переменных, который хранит адрес, даже было придумано специальное название - указатель, а то можно было бы просто говорить - адрес такой-то, адрес сякой-то). Указатель имеет имя - имя типа переменной, на которую указывает (так и говорят - именованный указатель). Указатели с разными именами не равнозначны: int* != char*, даже unsigned char* != char*, хотя казалось бы. Итого, у нас уже три свойства указателя:
  • это тип переменной в языке программирования
  • это имя
  • значение указателя - адрес, то есть указатель можно разименовывать
Поэтому утверждение 
Цитата(BearFear @  10.11.2012,  14:19 Найти цитируемый пост)
указатель и его тип, никак не влияет на значение на которое он указывает

в корне не верно. Если же иметь в виду некий адрес памяти (то есть значение указателя) и содержимое участка памяти по этому адресу, то да, они не влияют друг на друга. Про указатель Вы такое говорить не имеете права smile 

Это сообщение отредактировал(а) feodorv - 10.11.2012, 21:07


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
BearFear
Дата 10.11.2012, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



Вечно вы любите человеки не к селу вставлять перлы о знаниях и тем самым повышать свою самооценку. Я могу вам кинуть массу асмокода с расписанием комментов. Но зачем это делать ЗДЕСЬ? smile 4 байта читаются из недопустимой области, следовательно данные произвольные. О боже, неужели "проверочный" код настолько невидимый, что его никто не читал? smile Указатель указателем, а тип оригинальных данных на которые указатель указывает может иметь другую длину, отличимую от типа указателя. В лучшем случае данные "недочитаются" в худшем "перечитаются". И reinerpret как и приведение в Си может все поломать.  smile  подвох в классе заключался в первую очередь в контексте времени.

Задача класса получить на входе указатель на любой тип, а на выходе вернуть указатель на unsigned long long. Но доступ по такому указателю само собой же недопустим! Как бы мы внутри класса это не выворачивали бы!!! В этом заключался вопрос. Как это обойти? Как сделать, переделать... я мог вопрос поставить неправильно, в виду этого не матерюсь (еще бы матерился бы) на ваше непонимание.

Блин, если бы я не понимал что есть "указатель"... я бы написал бы корявый код с ошибками и у меня даже не возник бы сей вопрос!

И "о боже"x2! Об определителе типа, представьте, догадался уже давно и кажется где то выше писал про это smile
цЫтирую
Цитата

По сути, все упирается в число байт расположенных в блоке памяти на который указывает указатель. Их всего 5, uchar, ushort, ulong, ulonglong, uint. Сделать 5 дефайнов размера + флаг int или один из ...


Это сообщение отредактировал(а) BearFear - 10.11.2012, 19:12
PM MAIL   Вверх
BearFear
Дата 10.11.2012, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



Решением для такого класса могло бы стать:
- передача указателя на любой тип
- запись значения по указателю в посредника
- по деструктору класса запись обратно по полученному указателю

Но это пипец. Так недопустимо. Хотя, если ответственность за объекты очереди назначить на какой нибудь класс, то все могло бы получиться.
В общем всем спасибо ребят, всем ставлю плюсы (если не получится поставить, запишу на бумажке, поставлю после соответствующего числа сообщений моих). Задачу можно назвать решенной. Всем спасибо smile
PM MAIL   Вверх
baldina
Дата 10.11.2012, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(feodorv @  10.11.2012,  18:44 Найти цитируемый пост)
ЗЫ Для C++, как смутно припоминается, было какое-то элегантное решение вопроса, но увы, его не помню.

так volatile показал же как примерно это делается. Все сводится к 
Код

template <typename T>
size_t getSize (const T&) {
  return sizeof(T);
}

в итоге получаются детали такой, например, реализации:
http://insidecpp.ru/patterns/variant/
Цитата(BearFear @  10.11.2012,  13:19 Найти цитируемый пост)
Volatile, параметризация в вашем примере позволяет работать только с типами данных. А что если длина данного 45 байт?

да, только с типами. впрочем С++ язык строго типизированный, так что "не типов" не бывает, пример volatile покрывает все случаи. и для длины в 45, 2045, 200045 будет работать

Это сообщение отредактировал(а) baldina - 10.11.2012, 19:51
PM MAIL   Вверх
BearFear
Дата 10.11.2012, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 10.8.2012

Репутация: нет
Всего: нет



baldina, блин, игра слов получилась. С типами "данных" (а например не размеров).
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0697 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.