1

I have a problem with memory allocation in C and LVGL. The first part is the definitions.

typedef struct
{
    unsigned char Widgetcount;
    unsigned char index;
    lv_obj_t * btn[];
}AssetRADIOBUTTON;
typedef struct{

    lv_obj_t * tab;
    AssetRADIOBUTTON * Radio1;

}AssetSettingsSome;

typedef struct{
    
    lv_obj_t * ScreenMenuModule;
    unsinged char radioCOUNT;
    AssetSettingsSome Some;

}GUI_STRUCT_MODULES;

Now for initialization, if I call the memory allocation in subfunction, which works, in the subsubfunction with present code, it doesnt work. Code which works:

void CreateRadioButton(AssetRADIOBUTTON * Radio,lv_obj_t * tab,unsigned char RadioCount)
{
   Radio->Widgetcount = RadioCount;
   for(unsigned char i=0;i<RadioCount;i++)
       Radio->btn[i] = lv_checkbox_create(tab);
   Radio->index = 0;
}
void CreateDialog(GUI_STRUCT_MODULES * Settings)
{
   Settings->radioCOUNT = 4;
   Settings->Some.Radio1 = malloc(sizeof(*Settings->Some.Radio1) + Settings->radioCOUNT * sizeof(*Settings->Some.Radio1->btn));
   CreateRadioButton(Settings->Some.Radio1,Settings->ECG.tab,4);
}
void main(void)
{
    static GUI_STRUCT_MODULES GUI_MODULES;
    CreateDialog(&GUI_MODULES);
}

Code Which doesnt work

void CreateRadioButton(AssetRADIOBUTTON * Radio,lv_obj_t * tab,unsigned char RadioCount)
{
    Radio = malloc(sizeof(*Radio) + RadioCount * sizeof(*Radio->btn));
    Radio->Widgetcount = RadioCount;
    for(unsigned char i=0;i<RadioCount;i++)
        Radio->btn[i] = lv_checkbox_create(tab);
    Radio->index = 0;
}
void CreateDialog(GUI_STRUCT_MODULES * Settings)
{
   CreateRadioButton(Settings->Some.Radio1,Settings->ECG.tab,4);
}
void main(void)
{
    static GUI_STRUCT_MODULES GUI_MODULES;
    CreateDialog(&GUI_MODULES);
}    

Sorry for a bit long MVP.

1
  • C is pass by value; the argument Radio in CreateRadioButton is a local variable, and assigning to it has no effect on anything outside the function. So the effect of CreateRadioButton is to allocate some memory, write some stuff to it, and then leak it, while CreateDialog sees Settings->Some.Radio1 left unchanged by the call to CreateRadioButton. Commented Sep 30, 2021 at 15:17

1 Answer 1

1

Here's what is not working

void CreateRadioButton(AssetRADIOBUTTON * Radio, lv_obj_t * tab, unsigned char RadioCount)
{
    Radio = malloc(sizeof(*Radio) + RadioCount * sizeof(*Radio->btn));

You are storing the address of the allocated memory in Radio, which is a local variable. When you call CreateRadioButton(Settings->Some.Radio1...) you're just passing a pointer whose value you don't even look at. What you need to do, is tell your function where that pointer is, so it can be modified.

So, change the function signature so that it takes a pointer to a pointer, and pass the address of the pointer you want to change:

void CreateRadioButton(AssetRADIOBUTTON ** Radio,lv_obj_t * tab,unsigned char RadioCount)
{
    *Radio = malloc(sizeof(AssetRADIOBUTTON ) + RadioCount * sizeof(lv_obj_t));
    (*Radio)->Widgetcount = RadioCount;
    for(unsigned char i=0;i<RadioCount;i++)
        (*Radio)->btn[i] = lv_checkbox_create(tab);
    (*Radio)->index = 0;
}
...

CreateRadioButton(&Settings->Some.Radio1,Settings->ECG.tab,4);

Note the use of the & operator to get the address of the Radio1 pointer, and in CreateRadioButton the use of the * operator to dereference the Radio pointer-to-pointer, to get a pointer-to-AssetRADIOBUTTON.

If this syntax is too cumbersome, consider the following alternative.

    AssetRADIOBUTTON* p = *Radio;
    p->Widgetcount = RadioCount;
    for(unsigned char i=0;i<RadioCount;i++)
        p->btn[i] = lv_checkbox_create(tab);
    p->index = 0;

This creates a new variable, but with any decent compiler the resulting code will be the same.

Sign up to request clarification or add additional context in comments.

9 Comments

Now in this case, how can I access the contents of the Radio struct in CreateRadioButton? It says '*Radio' is a pointer; did you mean to use '->'?|
@vahidajal: by replacing that instance of . with ->. The error told you exactly how to fix it.
There is no . in CreateRadioButton. All of them are -> as you see. And this is surprising.
Please see my new edits. The arrow operator -> is still the correct way to access a structure member from a pointer, but an additional * operator is needed to dereference the pointer-to-pointer back to a simple pointer.
I use Codeblocks and it does throw the error. Tried what you said recently before you say on my own, but no success.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.