Манипулирование указателем на массив указателей

#c #pointers #data-structures #structure

#c #указатели #структуры данных #структура

Вопрос:

Пытаюсь написать фрагмент C для хранения и извлечения массива структурных указателей. Я скопировал свой фрагмент ниже.

Что я пытаюсь здесь сделать-

  1. метод Xos_get_cb_info_from_handle() должен возвращать указатель на базовый адрес структуры localclient.exit_cb. Которые, похоже, работают.
  2. После получения этого базового адреса я хотел бы индексировать в массив.
  3. В рамках этого упражнения temp1 должен хранить адрес 0-го индекса (первого элемента), temp2 должен хранить адрес 1-го индекса (второго элемента).

Мои наблюдения: (посмотрите на вывод в конце кода)

  1. Я получаю правильный базовый адрес здесь, в temp1, который равен 0x40300c
  2. Однако следующий элемент (индекс 1) должен быть 0x403010. На самом деле это 0x40301c. Похоже, что он увеличивается на размер структуры.

Что здесь происходит? Согласно арифметике указателя, C не должен увеличивать это на размер структуры (но на размер указателя.)

Кто-нибудь может помочь мне пролить некоторый свет на этот сценарий? Приветствуются любые предложения по изменению кода. Спасибо!

 #include <stdio.h>

#define X_PROCESS_DUMP_CB_MAX 3

typedef struct {
  void* cb_func;             /* pointer to callback function */
  unsigned cb_arg;           /* not interpreted by the framework*/
} X_cb_data_t;

typedef struct err_cb_t{
   X_cb_data_t Xos_cb;
   unsigned short priority;
   struct err_cb_t *next;
}Xos_exit_cb_t;

struct Xos_local_client {
    int x; //just placeholder
    Xos_exit_cb_t *exit_cb[X_PROCESS_DUMP_CB_MAX];
    int y; //just placeholder
};  

/*static global to this file, init this in main before accessing it*/
static struct Xos_local_client localclient;

int Xos_get_cb_info_from_handle(int client_handle, Xos_exit_cb_t** cb_head)
{
    *cb_head = (Xos_exit_cb_t *)amp;localclient.exit_cb[0];
    return 0; 
}

int main()
{
    int i = 0;

    /*init localclient here*/
    localclient.x =1;
    localclient.y =2;

    for(i =0; i< X_PROCESS_DUMP_CB_MAX; i  )
    {
        Xos_exit_cb_t *exit_cb_p = (Xos_exit_cb_t *)malloc(sizeof(Xos_exit_cb_t));
        localclient.exit_cb[i] = exit_cb_p;
        printf("amp;exit_cb_p: %p exit_cb_p: %pn", (unsigned int)amp;localclient.exit_cb[i],(unsigned int)exit_cb_p);
    }

    /*Test code that fails*/
    Xos_exit_cb_t** exit_cb_head;   /*Pointer to pointer of exit_cb*/   

    Xos_exit_cb_t **temp1;
    Xos_exit_cb_t **temp2;

    if (!Xos_get_cb_info_from_handle(3, exit_cb_head)) {

        temp1 = amp;(*exit_cb_head)[0];
        temp2 = amp;(*exit_cb_head)[1];

        printf("temp1: %p, temp2: %pn", temp1, temp2);
    }

    return 0;
}


/*Output*/
amp;exit_cb_p: 0x40300c exit_cb_p: 0xd18628
amp;exit_cb_p: 0x403010 exit_cb_p: 0xd426c0
amp;exit_cb_p: 0x403014 exit_cb_p: 0xd426d8
exit_cb_head: 0x40300c, temp1: 0x40300c, temp2: 0x40301c
 

Комментарии:

1. Назначение отсутствует? Xos_exit_cb_t** exit_cb_head = amp;(localclient.exit_cb[0]); ? А temp1 и temp2 — это «Xos_exit_cb_t *».

Ответ №1:

В вашем for цикле

 for(i =0; i< X_PROCESS_DUMP_CB_MAX; i  )
    {
        Xos_exit_cb_t *exit_cb_p = (Xos_exit_cb_t *)malloc(sizeof(Xos_exit_cb_t));
        localclient.exit_cb[i] = exit_cb_p;
        printf("amp;exit_cb_p: %p exit_cb_p: %pn", (unsigned int)amp;localclient.exit_cb[i],(unsigned int)exit_cb_p);
    }
 

вы повторяете массив указателей. Итак, вы видите приращение в соответствии с арифметикой указателя (приращение по размеру указателя)

Теперь, предполагая, что ваш код здесь пропустил копирование вставки, упомянутое в комментарии @reichhart, т.е.

 Xos_exit_cb_t** exit_cb_head = amp;(localclient.exit_cb[0]);
 

temp1 amp; temp2 (типа Xos_exit_cb_t * ) — это фактические адреса в памяти, где выделяется структура. Следовательно, базовый адрес смежных элементов будет разделен размером структуры.

Надеюсь, это поможет.