реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> указатель на указатель, помочь разобраться
Метценгерштейн
сообщение Jul 27 2018, 10:48
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Встретил в коде следующую конструкцию:

Код
ble_advdata_tk_value_t* oob_key;
err_code = nfc_tk_value_get(&oob_key);


где:

Код
typedef struct
{
  uint8_t tk[BLE_GAP_SEC_KEY_LEN];      /**< Array containing TK value in little-endian format. */
} ble_advdata_tk_value_t;


Код
ret_code_t nfc_tk_value_get(ble_advdata_tk_value_t ** pp_tk_value)
{
    if (m_tag_match)
    {
        *pp_tk_value = &m_device_tk;
        return NRF_SUCCESS;
    }
    else
    {
        return NRF_ERROR_NOT_FOUND;
    }
}


Есть вопрос. Как все проговорить что тут происходит?
Есть тип структуры ble_advdata_tk_value_t. Создали переменную- указатель на этот тип: oob_key.
Дальше? Передаем не просто адрес (сам указатель oob_key), а именно адрес этого указателя? А в ф-ии уже принимаем указатель на указатель?
Разыменовывали на один уровень вверх и по тому значению присвоили адрес уже массива.

А проще никак?
err_code = nfc_tk_value_get(oob_key);

и приняли:
Код
ret_code_t nfc_tk_value_get(ble_advdata_tk_value_t * pp_tk_value)
{
    if (m_tag_match)
    {
        pp_tk_value = &m_device_tk;
        return NRF_SUCCESS;
    }
    else
    {
        return NRF_ERROR_NOT_FOUND;
    }
}
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Jul 27 2018, 11:05
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Всё что со знаками вопроса - верно. Проще никак. Смысл указателя на указатель, что бы вернуть значение не копируя содержимое в буфер-аргумента.
Последний кусок кода напрочь ошибочный. "pp_tk_value = &m_device_tk;" скопирует указатель в аргумент. Но при выходе из функции oob_key не поменяется.
Go to the top of the page
 
+Quote Post
x893
сообщение Jul 27 2018, 11:44
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



есть передать сам указатель вы его изменить не сможете.
у них если if (m_tag_match) то указатель меняется.
Всё правильно сделано (согласно их логике).
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Jul 27 2018, 11:51
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Хорошо, а в моем приведенном примере- в чем ошибка? Не могу указателю сразу адрес присвоить разве?
Go to the top of the page
 
+Quote Post
x893
сообщение Jul 27 2018, 12:09
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Цитата(Метценгерштейн @ Jul 27 2018, 14:51) *
Хорошо, а в моем приведенном примере- в чем ошибка? Не могу указателю сразу адрес присвоить разве?

Присвоить можете, только указатель

ble_advdata_tk_value_t* oob_key;

не изменится.

P.S. Может книжечку почитать ?
"Стань профи С за 24 часа"
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Jul 27 2018, 12:25
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Не нашел в инете такой книжки.

Не совсем понимаю, зачем мне менять указатель. Точнее, я же в их логике его и меняю через разыменование и записи по нему.
Go to the top of the page
 
+Quote Post
_pv
сообщение Jul 27 2018, 12:39
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



на что будет указывать oob_key после выполнения функции в первом случае, и во втором?
ну или даже так: что произойдёт с переменной pp_tk_value после выхода из функции?

Цитата(Метценгерштейн @ Jul 27 2018, 19:25) *
Точнее, я же в их логике его и меняю через разыменование и записи по нему.

pp_tk_value = &m_device_tk;
где именно в данной строчке происходит разыменование указателя?
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Jul 27 2018, 12:54
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Разыменование происходит в оригинальном примере:
*pp_tk_value = &m_device_tk;

В моем случае, и в приведенном вами примере, конечно, разыменования не происходит. Просто идет присвоение адреса переменной типа указатель:
pp_tk_value = &m_device_tk;

Попробую ответить на первый вопрос.
После выполнения ф-ии oob_key будет указывать в первом случае на
&m_device_tk
т.к. происходит разыменование и присвоение адреса:
*pp_tk_value = &m_device_tk;

В моем случае- на то же. Понимаю, что где-то не прав, но не доходит почему.

pp_tk_value уйдет из области видимости и останется в записи oob_key. Все изменения будут внесены в oob_key .
Go to the top of the page
 
+Quote Post
_pv
сообщение Jul 27 2018, 13:49
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(Метценгерштейн @ Jul 27 2018, 19:54) *
В моем случае- на то же. Понимаю, что где-то не прав, но не доходит почему.
pp_tk_value уйдет из области видимости и останется в записи oob_key. Все изменения будут внесены в oob_key .

pp_tk_value это просто ещё один указатель, который указывает на то же на что и oob_key.
точнее указывал, а потом стал указывать на &m_device_tk.

в каком именно месте в вашем коде происходит запись в oob_key?
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Jul 27 2018, 14:32
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Цитата(_pv @ Jul 27 2018, 16:49) *
в каком именно месте в вашем коде происходит запись в oob_key?


*pp_tk_value = &m_device_tk;
в этом месте, т.к. работаю с указателями по памяти, а не по значению.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Jul 27 2018, 14:48
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(Метценгерштейн @ Jul 27 2018, 15:54) *
Понимаю, что где-то не прав, но не доходит почему.

Недостаток базовых знаний, вам совершенно не зря советуют книжки почитать. На уровне ассемблера при вызове функции все аргументы копируются в контекст функции. В самой функнции эти копии-аргументы можно менять как заблагорассудится, на источник своих значений они уже повлиять не могу. Поэтому и существуют указатели, что передать(скопировать) в функцию значение адреса объекта, который нужно изменить. Если бы вы программировали на с++, то вы могли бы(но делать так не стоит использовать ссылку для того что бы ваш пример заработал:
Цитата
ret_code_t nfc_tk_value_get(ble_advdata_tk_value_t *& pp_tk_value)

И тогда по ссылке изменения вернуться в oob_key. Но делать так, повторюсь, не надо. Нужно понять для чего нужны указатели и указатель на указатель.
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Jul 27 2018, 14:50
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Так я же не против почитать что-то) Читал много, но с этим вопросом не сталкивался. Если есть под рукой статья, где это все наглядно демонстрируется, то с удовольствием посмотрю.
Ну а в чем я в предыдущем посте не прав?

*pp_tk_value = &m_device_tk;
в этом месте, т.к. работаю с указателями по памяти, а не по значению.

Это тоже самое что вы и сказали:
На уровне ассемблера при вызове функции все аргументы копируются в контекст функции. В самой функнции эти копии-аргументы можно менять как заблагорассудится, на источник своих значений они уже повлиять не могу. Поэтому и существуют указатели, что передать(скопировать) в функцию значение адреса объекта, который нужно изменить.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Jul 27 2018, 15:02
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



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

Цитата(Метценгерштейн @ Jul 27 2018, 17:50) *
*pp_tk_value = &m_device_tk;

Если ble_advdata_tk_value_t * pp_tk_value , в этом коде вы просто испортили начало массива pp_tk_value каким-то левым для содержимого этого массива адресом.
Go to the top of the page
 
+Quote Post
DASM
сообщение Jul 27 2018, 15:22
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Kabdim @ Jul 27 2018, 17:48) *
Но делать так, повторюсь, не надо.
Почему?
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Jul 27 2018, 15:24
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Код
ret_code_t nfc_tk_value_get(ble_advdata_tk_value_t ** pp_tk_value)
{
    if (m_tag_match)
    {
        *pp_tk_value = &m_device_tk;
        return NRF_SUCCESS;
    }
    else
    {
        return NRF_ERROR_NOT_FOUND;
    }
}

Это код из оригинального примера.
Произошло разыменование указателя и записался адрес чего- то. Но, если бы на вход пришел адрес массива, то да. А посмотрите внимательно- пришел адрес адреса))

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


Полностью согласен. Эти вещи я знаю отлично. Это не тот вопрос, который мне не понятен. Для того и передают в ф-ю адрес переменной. Изменив ее там, она поменяется и там откуда ее переслали.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th April 2024 - 05:11
Рейтинг@Mail.ru


Страница сгенерированна за 0.01506 секунд с 7
ELECTRONIX ©2004-2016