Русский / Russian English / Английский

Сейчас на форуме: rmn, bernal1, jinoweb, ARCHANGEL, haous (+3 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS ·

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

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

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

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

Ранг: 80.6 (постоянный)
Статус: Участник

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

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

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

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


Ранг: 604.8 (!)
Статус: Модератор
Research & Development

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

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

v00doo опередил


Ранг: 150.7 (ветеран)
Статус: Участник

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

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

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

ptr = (LPCSTR) &number;

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

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

Ранг: 421.4 (мудрец)
Статус: Участник

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

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



str = (LPСSTR) addr;


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

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

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

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


Ранг: 324.3 (мудрец)
Статус: Участник

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

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

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

Ранг: 157.0 (ветеран)
Статус: Участник

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

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

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

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

Ранг: 421.4 (мудрец)
Статус: Участник

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

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


Ранг: 324.3 (мудрец)
Статус: Участник

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

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

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

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

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


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


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

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

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



Ранг: 607.4 (!)
Статус: Участник
_Вечный_Студент_

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

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


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

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


Ранг: 421.4 (мудрец)
Статус: Участник

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

--post removed--


Ранг: 324.3 (мудрец)
Статус: Участник

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

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

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


Ранг: 1128.2 (!!!!)
Статус: Участник

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

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



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



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

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



Ранг: 607.4 (!)
Статус: Участник
_Вечный_Студент_

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

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

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

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


Ранг: 421.4 (мудрец)
Статус: Участник

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

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

) Более чем.

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

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

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



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

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

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

Ранг: 17.7 (новичок)
Статус: Участник

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

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

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



Ранг: 1128.2 (!!!!)
Статус: Участник

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

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


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

Ранг: 421.4 (мудрец)
Статус: Участник

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

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

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

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

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

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

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


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


Ранг: 1044.8 (!!!!)
Статус: Участник

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

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

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

Ранг: 157.0 (ветеран)
Статус: Участник

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

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


Ранг: 150.7 (ветеран)
Статус: Участник

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

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

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

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

не оно?

Ранг: 589.6 (!)
Статус: Модератор

Создано: 4 апреля 2017 18:48 New!
Цитата · Личное сообщение · #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 (нарушитель)
Статус: Участник

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

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

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

Ранг: 421.4 (мудрец)
Статус: Участник

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

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

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

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

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

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



Ранг: 607.4 (!)
Статус: Участник
_Вечный_Студент_

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

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

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


Ранг: -26.7 (нарушитель)
Статус: Участник

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

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


Ранг: 329.3 (мудрец)
Статус: Участник

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

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

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

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


Ранг: -26.7 (нарушитель)
Статус: Участник

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

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

Видеокурс ВЗЛОМ