Pass struct to event with user_data


Program crash when i access user data struct

What MCU/Processor/Board and compiler are you using?

M5Stack Fire

What LVGL version are you using?


What do you want to achieve?

I want to pass a structure to a event and access it

What have you tried so far?

When i try to run the program its crashing when i want to load the new screen in the event. And for debugging i actually printed all pointer adress to the Serial output. What i found out is that the adress for the pointer on the structure is correct, but when i want to access a object the screen for example, then its not correct anymore. For example when i run the program i get following output on the Serial line.

id  r2 0x3ffb275c
id  r2 screen 0x3ffc6c98
id  r2 next_relais 0x3ffb275c
id  r2 screen next_relais 0x3ffcf298

The id of the original structure created in the setup function is 0x3ffb275c and the id of the screen object is 0x3ffc6c98. The id of the passed structure to the event is 0x3ffb275c its the same as in the create and correct. When i access the object screen then its not the same and i don’t know why 0x3ffcf298 and that should be the reason why its crashing, but i dont know why its not the right point the screen.

Here is my structure

typedef struct {
  char name[10];
  lv_obj_t *screen_obj;
  lv_obj_t *btn_obj;
  lv_obj_t *label_obj;
  lv_obj_t *switch_obj;
  lv_group_t *group;
} relais_t;

I have created a function from which i create buttons in my setup function

relais_t create_relais(lv_obj_t *screen_main, const char *name, int row, int col) {
  relais_t rel_obj;

  strcpy(, name);

  rel_obj.screen_obj = lv_obj_create(NULL);
  lv_obj_set_size(rel_obj.screen_obj, 300, 220);
  lv_obj_set_flex_flow(rel_obj.screen_obj, LV_FLEX_FLOW_ROW_WRAP);

  rel_obj.btn_obj = lv_btn_create(screen_main);
  lv_obj_set_grid_cell(rel_obj.btn_obj, LV_GRID_ALIGN_STRETCH, col, 1,
                            LV_GRID_ALIGN_STRETCH, row, 1);
  rel_obj.label_obj = lv_label_create(rel_obj.btn_obj);
  lv_label_set_text_fmt(rel_obj.label_obj,, 0, 1);
  // lv_obj_add_style(rel_obj.btn_obj, &style_btn, 0);
  // lv_obj_add_style(rel_obj.btn_obj, &style_btn_red, LV_STATE_PRESSED);
  // lv_obj_add_style(rel_obj.btn_obj, &style_btn_blue, LV_STATE_FOCUSED);
  lv_obj_add_event_cb(rel_obj.btn_obj, event_relais_btn, LV_EVENT_CLICKED, &rel_obj);
  rel_obj.switch_obj = lv_switch_create(rel_obj.screen_obj);
  lv_obj_add_state(rel_obj.switch_obj, LV_STATE_CHECKED); = lv_group_create();
  lv_group_add_obj(, rel_obj.switch_obj);
  lv_obj_add_event_cb(rel_obj.switch_obj, event_switch, LV_EVENT_ALL, &rel_obj);

  if (strcmp("R1", name) == 0) {
    char buffer[80];
    sprintf(buffer, "id  r2 %p\n", &rel_obj);

    sprintf(buffer, "id  r2 screen %p\n", rel_obj.screen_obj);

  return rel_obj;

This block is only there to print the pointer adress for debugging

  if (strcmp("R1", name) == 0) {
    char buffer[80];
    sprintf(buffer, "id  r2 %p\n", &rel_obj);

    sprintf(buffer, "id  r2 screen %p\n", rel_obj.screen_obj);

And this is my code for the event

static void event_relais_btn(lv_event_t * e) {
  next_relais = (relais_t *) lv_event_get_user_data(e);

  char buffer[80];
  sprintf(buffer, "id  r2 next_relais %p\n", next_relais);
  sprintf(buffer, "id  r2 screen next_relais %p\n", next_relais->screen_obj);


I also tried to create a function with a void * pointer something like and it is working without any problems.

void test(void *data) {
 relais_t *test_data = (relais_t*) data;

rel_obj is created on the stack in create_relais and the address is passed to lv_obj_add_event_cb. By the time the event is called the memory is no longer valid.

ok yes my c skills are a little bit rusty because i have programmed a lot in python, ok i need to define the objects in another way i think i understood the problem now. i should pull out my old c book again and refresh my skills. thank you for your time.