Сейчас на форуме: jinoweb, bartolomeo, rmn (+5 невидимых)

 eXeL@B —› Программирование —› Указатели
. 1 . 2 . >>
Посл.ответ Сообщение

Ранг: 3.6 (гость)
Активность: 0.010
Статус: Участник

Создано: 19 марта 2017 01:22
· Личное сообщение · #1

Привет!
Пытаюсь разобраться с темой указателей в с, никак не могу найти ответ на один вопрос. В общем, есть примерно такой код:
DWORD64 addr = 12345...;
LPCSTR str;
addr - это переменная в которой лежит некий адрес. Вопрос - как присвоить этот адрес str? Иными словами, как сделать так, чтобы указатель str, ссылался на адрес который лежит в addr? Также известно что по адресу 12345... находятся символьные данные.



Ранг: 80.6 (постоянный), 194thx
Активность: 0.10.04
Статус: Участник

Создано: 19 марта 2017 02:20 · Поправил: v00doo
· Личное сообщение · #2

В C и C++ строгая типизация, как минимум DWORD64 это 8 байт в памяти и это число, а LPCSTR это указатель на строку заканчивающуюся нулем, то есть это по сути указатель на массив байт.

DWORD64 number = 12345;
DWORD64 *ptr = &number; // ptr - и есть указатель.

Но если принудительно, то скастуй:
LPCSTR ptr = (LPCSTR )number;
да, поправка, если number это уже некий адрес сампо себе то как выше, если надо НА это значение указатель, то как написал -=AkaBOSS=-.




Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 19 марта 2017 02:21
· Личное сообщение · #3

через оператор *

v00doo опередил

-----
EnJoy!





Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 19 марта 2017 02:35 · Поправил: -=AkaBOSS=-
· Личное сообщение · #4

Rew пишет:
Вопрос - как присвоить этот адрес str

спроси гугл про приведение типов
или ВОТ например статья, про с++ каст

ptr = (LPCSTR) &number;

v00doo пишет:
LPCSTR ptr = (LPCSTR )number;

по ссылке надо присваивать, иначе при обращении к указателю будет значение как адрес юзать
а хотя да, правильно. не дочитал условие задачи.
Если нужно число интерпретировать как адрес данных в памяти, тогда вариант v00doo - правильный.



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 19 марта 2017 02:49 · Поправил: dosprog
· Личное сообщение · #5

Rew пишет:
DWORD64 addr = 12345...;
LPCSTR str;



str = (LPСSTR) addr;





Ранг: 3.6 (гость)
Активность: 0.010
Статус: Участник

Создано: 19 марта 2017 17:39
· Личное сообщение · #6

Всем спасибо.
Решение выглядит так:
DWORD64 addr = 12345;
DWORD64 *p_buf;
LPCSTR str;

p_buf = (DWORD64*)addr;
str = (LPCSTR)*p_buf;




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 19 марта 2017 18:18
· Личное сообщение · #7

Rew
столько лишнего кода ))

dosprog Вам правильно написал. Этого достаточно вообще

-----
IZ.RU




Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 20 марта 2017 00:52
· Личное сообщение · #8

Rew пишет:
Решение выглядит так:
DWORD64 addr = 12345;
DWORD64 *p_buf;
LPCSTR str;

p_buf = (DWORD64*)addr;
str = (LPCSTR)*p_buf;

Так ты присвоил str адрес, который лежит по адресу 12345 (т.е. присвоил в качестве адреса первые 4-8 байт из символьных данных).



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 20 марта 2017 01:41 · Поправил: dosprog
· Личное сообщение · #9

Ключ есть в MSVC - "/Fa" - он помогает посмотреть, что там нагенерилось.
А у линкера есть ключ "/MAP", он тоже бывает полезен, вместе с HIEW32 и LOADMAPEX.HEM.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 20 марта 2017 06:08
· Личное сообщение · #10

Большие исследования "защиты указателей в си" провели

Самый первый верный ответ v00doo не проигнорировал разве что Jupiter

v00doo пишет:
DWORD64 number = 12345;
DWORD64 *ptr = &number; // ptr - и есть указатель.

Но если принудительно, то скастуй:
LPCSTR ptr = (LPCSTR )number;


Правда, лишних слов много. Исходя из вопроса:
Rew пишет:
addr - это переменная в которой лежит некий адрес. Вопрос - как присвоить этот адрес str?


Правильным ответом будет именно LPCSTR ptr = (LPCSTR )number;

Rew
А что же будет, когда доберётесь до указателей на указатели, массивов указателей, и указателей на массивы указателей? ))

-----
IZ.RU


| Сообщение посчитали полезным: plutos


Ранг: 622.6 (!), 521thx
Активность: 0.330.89
Статус: Участник
_Вечный_Студент_

Создано: 20 марта 2017 06:49
· Личное сообщение · #11

DenCoder пишет:
А что же будет, когда доберётесь до указателей на указатели, массивов указателей, и указателей на массивы указателей? ))


а указатели на функции, принимающие в качестве параметров указатели на массивы указателей на указатели?
Страшно подумать!

-----
Give me a HANDLE and I will move the Earth.


| Сообщение посчитали полезным: DenCoder, Gideon Vi

Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 20 марта 2017 12:44 · Поправил: dosprog
· Личное сообщение · #12

--post removed--




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 20 марта 2017 13:58
· Личное сообщение · #13

dosprog
Вот какой тебе от этого профит? Все ведь всё уже написали )

А если сейчас напишу, что (void*) для методов классов не прокатит? И пошла поехала флудилка? Сам начинаешь флудить, а потом кого-то в этом обвиняешь!

-----
IZ.RU





Ранг: 1131.7 (!!!!), 447thx
Активность: 0.670.2
Статус: Участник

Создано: 23 марта 2017 03:04
· Личное сообщение · #14

C охуенен Столько возможностей выстрелить себе в ногу!



как так, легитимно же, ёба?!



Средний студент через такое рискует до указателей не дойти.

| Сообщение посчитали полезным: plutos


Ранг: 622.6 (!), 521thx
Активность: 0.330.89
Статус: Участник
_Вечный_Студент_

Создано: 23 марта 2017 03:23
· Личное сообщение · #15

Для тех, кто хочет по-настоящему разобраться с темой указателей, могу порекомендовать очень толковую книгу:
"POINTERS ON C", by Kenneth A. Reek.

Никакой "воды", 600 страниц и все по теме. Масса примеров отличного кода.
Уверен, что ее легко найти на интернете.

-----
Give me a HANDLE and I will move the Earth.


| Сообщение посчитали полезным: Gideon Vi, Rew

Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 23 марта 2017 09:34 · Поправил: dosprog
· Личное сообщение · #16

Gideon Vi пишет:
C охуенен

) Более чем.

Gideon Vi пишет:
как так, легитимно же, ёба?!

) Да, эта фича функции printf() доставляет траблы.
В каком-то дремучем году даже пришлось делать функцию hexdump(), которая не помогла.
Впрочем, если уметь пользоваться, то это даже удобно.

Спецификаторы "%" влияют только на способ интерпретации данных в стеке, при выводе, динамически.
Сам же порядок формирования стека закладывается статически при компиляции, на основании типов данных в аргументах.
Оно должно соответствовать, но зависит от внимательности



Добавлено спустя 31 минуту
plutos пишет:
Уверен, что ее легко найти на интернете.

) А вот я не уверен. Сходу нашлась оная только --> на китайском языке. <--
- Впечатление плохое - там одни крюки, читать невозможно

--Добавлено--
А вот тут, вроде, --> на английском <--
Причём есть отсканированная версия (65Мб), и оцифрованная (4Мб).



Ранг: 17.7 (новичок), 13thx
Активность: 0.010
Статус: Участник

Создано: 23 марта 2017 10:20 · Поправил: Artem_N
· Личное сообщение · #17

dosprog, это потому что гугл/яндекс - днище!
Вот тут всё находится

| Сообщение посчитали полезным: sefkrd, Gideon Vi, DenCoder, Isaev


Ранг: 1131.7 (!!!!), 447thx
Активность: 0.670.2
Статус: Участник

Создано: 23 марта 2017 12:35
· Личное сообщение · #18

dosprog пишет:
Сходу нашлась оная только --> на китайском языке. <--


http://appnee.com/pointers-on-c-1st-edition-hd-pdf-source-code-answers/



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 23 марта 2017 12:43 · Поправил: dosprog
· Личное сообщение · #19

Спс. Выше уже дал ссылку, там несколько вариантов оцифровки.
В том числе и "распознанный текст" размером 4Мб.



Ранг: 3.6 (гость)
Активность: 0.010
Статус: Участник

Создано: 04 апреля 2017 18:26 · Поправил: Rew
· Личное сообщение · #20

Тааак...
Я сейчас перечитал ответы и понял что я наверное не совсем внятно сформулировал вопрос.
Решил накидать схему, чтобы стало понятнее, возможно у кого-то возникнет подобный вопрос:

В общем мне нужно было как-то добраться до строковых данных и единственное решение которое я нашел:

Code:
  1. DWORD64 addr = 0x456;
  2. DWORD64 *p_buf;
  3. LPCSTR str;
  4.  
  5. p_buf = (DWORD64*)addr;
  6. str = (LPCSTR)*p_buf;


Интересно можно ли это сделать по другому(на чистом си)?




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 04 апреля 2017 18:43 · Поправил: reversecode
· Личное сообщение · #21

что по другому ?

LPCSTR str = (LPCSTR)*(DWORD64*)0x456;



Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 04 апреля 2017 18:45 · Поправил: rmn
· Личное сообщение · #22

Code:
  1. DWORD64 addr = 0x456;
  2. LPCSTR str = **((LPCSTR*)addr);





Ранг: 150.3 (ветеран), 175thx
Активность: 0.160.07
Статус: Участник

Создано: 04 апреля 2017 18:45 · Поправил: -=AkaBOSS=-
· Личное сообщение · #23

разыменовывать указатель можно больше одного раза при необходимости

DWORD64 addr = 0x456;
LPCSTR str = **(LPCSTR**)addr;

на пустом проекте собирается в код типа такого:
mov eax, [456]
mov eax, [eax]

не оно?



Ранг: 590.6 (!), 408thx
Активность: 0.360.18
Статус: Модератор

Создано: 04 апреля 2017 18:48
· Личное сообщение · #24

Code:
  1. p_buf = (DWORD64*)addr; // кастуешь число в типизированный указатель. теперь можно вынуть число заданного типа через *
  2. str = (LPCSTR)*p_buf; // вынимаешь число и кастуешь его в LPCSTR

в данном случае логично было бы p_buf объявить как LPCSTR*
Code:
  1. LPCSTR* p_buf = (LPCSTR*) 0x456;
  2. LPCSTR str = *p_buf;


-----
старый пень




Ранг: -26.7 (нарушитель), 7thx
Активность: 0.060.08
Статус: Участник

Создано: 23 августа 2017 05:21
· Личное сообщение · #25

Всем здравствуйте.

Подскажите пожалуйста, где я ошибся --> в этом коде <--? Вроде бы все просто, но, тем не менее, что-то я явно недопонимаю в структурах и указателях в них. Код компилируется, но при запуске, отладке в VS 2015 - вылетает с ошибкой и исключением.



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 23 августа 2017 05:40 · Поправил: dosprog
· Личное сообщение · #26

Code:
  1. VstEvents2.events[0] -> deltaFrames = 7;

Запись в никуда.

Прежде нужно инициализировать указатель

Code:
  1. VstEvents2.events[0] = &VstEvent1;
  2. VstEvents2.events[0] -> deltaFrames = 7;


| Сообщение посчитали полезным: plutos, sty, Gideon Vi


Ранг: 622.6 (!), 521thx
Активность: 0.330.89
Статус: Участник
_Вечный_Студент_

Создано: 23 августа 2017 06:18
· Личное сообщение · #27

Если бы вы поставили breakpoint на то место, где Exception is thrown, то легко бы увидели, что VstEvents2.events[0] указывает в никуда.
Кроме того, сам тип 0xC0000005 Access Violation уже служит подсказкой.

-----
Give me a HANDLE and I will move the Earth.


| Сообщение посчитали полезным: sty, Gideon Vi

Ранг: -26.7 (нарушитель), 7thx
Активность: 0.060.08
Статус: Участник

Создано: 23 августа 2017 07:34
· Личное сообщение · #28

dosprog, plutos спасибо огромное! Ну вы, конечно, профи еще те - иначе и не скажешь! Прям, "камень с души" сняли. Как сказал мне один мой знакомый: а что ты хочешь, крэкеры-хакеры - они и есть крекеры-хакеры, если, конечно, настоящие, для них этот твой C/C++ - как пару семечек сощелкнуть. Не стал я с ним спорить на этот раз, потому как, что называется - ни прибавить, ни убавить.




Ранг: 338.5 (мудрец), 348thx
Активность: 2.112.42
Статус: Участник

Создано: 26 августа 2017 01:10
· Личное сообщение · #29

Имхо ответ нужно искать не в языковых конструкциях. А если вам интересна не сишка, а какой то другой язык, в котором тоже есть указатели, то как его понять ?

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

-----
vx


| Сообщение посчитали полезным: sty

Ранг: -26.7 (нарушитель), 7thx
Активность: 0.060.08
Статус: Участник

Создано: 26 августа 2017 19:58
· Личное сообщение · #30

difexacaw, спасибо за совет, приму к сведению. Вообще, тема указателей - та еще штучка. Когда дело касается каких-то простых конструкций типа: int* pA = & A; - тут, конечно, ничего сложного нет. Когда же дело доходит до конструкций типа: char *(*(**foo[][8])())[]; или void (*signal(int, void (*fp)(int)))(int); - то тут, естественно, даже опытный программист может задуматься надолго. Поэтому, видимо, при каких-то сложных объявлениях - нужно учиться разбираться с помощью отладчика и знать побольше сообщений об ошибках, которые выдают компиляторы. В общем, век живи, век учись ... ну а дальше все знают.


. 1 . 2 . >>
 eXeL@B —› Программирование —› Указатели
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати